【问题标题】:Xml serialization library for iPhone Apps [closed]iPhone 应用程序的 XML 序列化库 [关闭]
【发布时间】:2010-10-30 23:30:04
【问题描述】:

Apple 提供了 NSArchiver 和 NSUnachriver 用于对象序列化/反序列化,但这不能处理任何自定义 xml 架构。因此,必须手动使用任何自定义 xml 模式的数据填充对象结构。 由于 iPhone 开发者社区正在迅速发展,许多新手程序员都对处理可用的 xml 解析可能性感到绝望。

iPhone SDK 仅提供 NSXmlParser 用于 xml 解析,这对于读取 xml 文件的某些部分更有用,而不是填充整个对象结构,这真的很痛苦。

另一种可能性是著名的 libxml 库,它是用 ANSI C 编写的 - 对于开始使用 Objective-c 编程并且以前从未学过正确 C 的人来说并不容易使用。事件有很多可用的包装器,处理 xml 对新手来说可能很痛苦。

我的想法在这里发生了。自动填充对象结构的 XmlSerializer 库可以使它更容易,并提高许多程序员的应用程序质量。 我的想法应该是这样的:

xml 文件

<Test name="Michael" uid="28">
    <Adress street="AlphaBetaGammastrasse 1" city="Zürich" postCode="8000" />

  <Hobbies>
    <Hobby describtion="blabla"/>
    <Hobby describtion="blupblup"/>
  </Hobbies>
</Test>

要填写的课程

@interface Test : NSObject {
    NSString *name;
    Adress *adress;
    NSArray *hobbies;
    int uid;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) Adress *adress;
@property (nonatomic, retain) NSArray *hobbies;
@property (nonatomic, readwrite) int uid;
@end

@interface Adress : NSObject {
    NSString *street;
    NSString *city;
    int postCode;
}
@property (nonatomic, copy) NSString *street;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, readwrite) int postCode;
@end

xml 序列化程序应该如何工作

NSError *error = nil;
XMLSerializer *serializer = [[XMLSerializer alloc] init];
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TestFile" ofType:@"xml"]];
Test *test = [serializer deserializeWithData:data error:&error];

填充对象结构只需要一行代码:

Test *test = [serializer deserializeWithData:data error:&error];

这将非常容易使用,任何新手程序员都可以使用它。对于更高级的用法,可以配置序列化程序。

您认为,这对 iPhone 和 OSX 应用程序来说会是一个有用且受欢迎的库吗?

编辑: 你可以看到项目here,但距离发布还很远。

【问题讨论】:

标签: iphone objective-c xml serialization


【解决方案1】:

这是一个非常好的主意,在实现方面我会通过实现 NSXMLArchiver 和 NSXMLUnarchiver 作为 NSCoder 的子类来实现。这样,任何符合 NSCoding 协议的类都可以轻松地与 XML 进行序列化。

序列化为 XML 时的一个性能损失是作为属性的原始值,因为您无法保证对象请求数据进行编码的顺序。因此,如果属性是您想要的,那么它在内存缓冲区中将会非常大。但这将是一个有趣的练习。

至于它有多受欢迎?我认为不是那么受欢迎。用例太小了。

  • 设备到设备 - 简单地使用 NSKeyedArchiver 更加简单,而且更加紧凑。
  • 设备到新服务器 - 新服务器也必须实现相同的方案,序列化为 Java、C# 或其他。
  • 设备到现有服务器 - XML 格式已经固定,而且很可能不接近这个。

【讨论】:

    【解决方案2】:

    您所描述的内容隐藏在ObjectiveResourceimplementations 中,它同时支持 JSON 和 XML。应该很容易分叉它并通过丢弃所有连接管理将其精简为解析。

    【讨论】:

      【解决方案3】:

      NSKeyedArchiver 的工作原理正是因为它不会尝试映射到 XML 模式。很多很多 XML 模式的设计都很糟糕(即它们将内存中的对象结构转换为外部表示格式)。关键问题是文档的设计应该从文档的角度来看是有意义的,然后需要映射到您想要的对象的任何内存布局。是否见过带有大量“refid”属性的 XML 文档引用文档的其他部分?这些通常是从关系数据库音译而来的,关系数据库只是在结果集上加上尖括号。

      因此,从假设 XML 文档与其代码表示之间的一对一映射开始,除了最简单的情况外,几乎注定要失败。试想一下,如果 HTML 是围绕用于在第一个浏览器中实例化文档的 C++ 对象设计的,那么我们今天的 HTML 会是什么样子……(嗯,更像是 Objective-C,但是嘿……)

      关于 NSKeyedArchiver 的要点是,您可以在不破坏加载旧版本的能力的情况下改进数据结构。使用某种自动化的 instance-var-to-element 映射(正确地)做到这一点非常困难。

      【讨论】:

      • OP 的示例是一个数据模型,其中包含对序列化有意义的简单字段。在我看来,问题更多是关于如何以 Apple 的 plist 格式以外的格式序列化/反序列化 XML。很可能,这将用于与不运行 OSX 的 Web 服务进行数据通信(因此它不是围绕 plist 设计的)。因此,理想情况下,您应该为模式中的每个项目编写一个具有属性的模型对象,并使用它来序列化来自服务的 XML 结果值。
      • 此外,OP 的示例是一个“从文档角度”有意义的 XML 文档。在这种情况下,更有可能构建了支持正在使用的文档格式的 Objective-C 对象。这是完全可以接受的。他们正在寻找一种简单的方法来将文档转换为内存中的表示,而无需为每个对象编写自定义解析代码。
      【解决方案4】:

      我一直在努力满足该领域的需求,并认为这将是一个好主意。我不得不欺负我的 .net 服务来返回 JSON 以便在 iPhone 上轻松使用。一个像样的序列化库会很棒。

      【讨论】:

        【解决方案5】:

        我已经启动了一个类似的开源项目。我将其命名为 SAMIXOS。您可以访问此页面并尝试一下。 它处于初始开发阶段。它的工作原理与 Enyra 所要求的类似。

        很快我会提供一个示例代码。

        http://sourceforge.net/projects/samixos/

        萨米

        【讨论】:

        • 嗨萨米。 .我在将您的库添加到我的项目时遇到问题。你有一个示例项目吗??
        【解决方案6】:

        我开了一个相关的开源项目,XML stream writer for iOS

        • 用 Objective-C 编写,单个 .h。和 .m 文件
        • 一个@protocol 用于命名空间支持,一个用于不支持

        例子:

        // allocate serializer
        XMLWriter* xmlWriter = [[XMLWriter alloc]init];
        
        // start writing XML elements
        [xmlWriter writeStartElement:@"Root"];
        [xmlWriter writeCharacters:@"Text content for root element"];
        [xmlWriter writeEndElement];
        
        // get the resulting XML string
        NSString* xml = [xmlWriter toString];
        

        这会产生以下 XML 字符串:

        <Root>Text content for root element</Root>
        

        根据我的经验,用于将对象从一个模型(内存中的对象)映射到另一个模型(某些 XML 模式)的经济高效的工具并不存在,因为仍然必须以某种方式表达逻辑。您最好使用您熟悉的工具(代码!?)来完成工作。

        但是如果你坚持使用这样的工具,那么你的方法就是让你的对象模型和 XML 模型一样。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-26
          • 1970-01-01
          • 2011-02-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多