RaptureXML是一个简单的基于块的iOS平台XML库,它提供了一种表达性API,让XML处理变得极其有趣。
你告诉我。在Objective-C中处理XML既糟糕又令人沮丧,而且生成的代码永远都是难以阅读的。我受够了!RaptureXML通过在libxml2之上提供强大的新接口来解决这个问题。
RXMLElement *rootXML = [RXMLElement elementFromXMLFile:@"players.xml"];
[rootXML iterate:@"players.player" usingBlock: ^(RXMLElement *e) {
NSLog(@"Player #%@: %@", [e attribute:@"number"], [e child:@"name"].text);
}];
当涉及到Objective-C中的XML处理时,RaptureXML改变了游戏规则。正如你所看到的代码,你只需要几秒钟就能理解这段代码的作用。无需浪费数组和冗长的循环。代码易于阅读和维护。
我觉得不需要再说更多了。
将RaptureXML添加到您的项目的推荐方法是使用CocoaPods。只需将“RaptureXML”添加到您的Podfile。
如果您要手动安装,只需要几个简单的步骤
RaptureXML支持ARC。您可以自由使用任何版本的LLVM或gcc! (尽管您现在应该使用LLVM。)
RaptureXML支持ARC。事实上,它只支持ARC。如果您还在运行一个不使用ARC的项目,RaptureXML可能不适合您。
RaptureXML通过两个步骤处理XML:加载和路径。这意味着您首先从任何来源加载XML,例如文件、数据或字符串。然后,您只需使用其查询语言找到您需要的内容。
您可以使用以下任何构造函数加载XML
RXMLElement *rootXML = [RXMLElement elementFromXMLString:@"...my xml..." encoding:NSUTF8StringEncoding];
RXMLElement *rootXML = [RXMLElement elementFromXMLFile:@"myfile.xml"];
RXMLElement *rootXML = [RXMLElement elementFromXMLFilename:@"myfile" elementFromXMLFilename:@"xml"];
RXMLElement *rootXML = [RXMLElement elementFromXMLData:myData];
这些构造函数返回一个表示顶层标签的RXMLElement对象。现在,您可以用任何数量的方式查询数据。
假设您的XML看起来像这样
<team year="2011" name="New York Mets">
<players>
<coach>
<name>Terry Collins</name>
<year>1</year>
</coach>
<player number="7">
<name>Jose Reyes</name>
<position>SS</position>
</player>
<player number="16">
<name>Angel Pagan</name>
<position>CF</position>
</player>
<player number="5">
<name>David Wright</name>
<position>3B</position>
</player>
...
</players>
</team>
首先,我们需要加载XML
RXMLElement *rootXML = [RXMLElement elementFromXMLFile:@"players.xml"];
我们可以立即查询顶层标签名称
rootXML.tag --> @"team"
我们可以使用以下方式读取属性
[rootXML attribute:@"year"] --> @"2011"
[rootXML attribute:@"name"] --> @"New York Mets"
我们可以使用以下方式获取players标签
RXMLElement *rxmlPlayers = [rootXML child:@"players"];
如果需要,我们也可以获取所有的单个player标签,使用以下方式
NSArray *rxmlIndividualPlayers = [rxmlPlayers children:@"player"];
从这里,我们可以处理单个玩家并感到高兴。这比我们见过的任何其他XML库都要好很多,但RaptureXML可以使用查询路径使这个过程变得极其简单。让我们使用查询路径来简化我们的代码
[rootXML iterate:@"players.player" usingBlock: ^(RXMLElement *player) {
NSLog(@"Player: %@ (#%@)", [player child:@"name"].text, [player attribute:@"number"]);
}];
您的代码块在单行中就传入了表示每个玩家的RXMLElement!或者,您可以将其缩短为
[rootXML iterate:@"players.player" usingBlock: ^(RXMLElement *player) {
NSLog(@"Player: %@ (#%@)", [player child:@"name"], [player attribute:@"number"]);
}];
这也适用,因为RXMLElement#description会返回标签的文本。查询路径使用通配符时更加强大。如果我们想要得到球队中每个人的名字,无论是球员还是教练,我们可以使用通配符来获取它
[rootXML iterate:@"players.*.name" usingBlock: ^(RXMLElement *name) {
NSLog(@"Name: %@", name.text);
}];
通配符会处理所有标签而不是你会命名的那些。您也可以使用通配符遍历一个元素的子元素
[rootXML iterate:@"players.coach.*" usingBlock: ^(RXMLElement *e) {
NSLog(@"Tag: %@, Text: %@", e.tag, e.text);
}];
这给我们所有教练的标签。容易吗?
如果您不想使用自定义的RaptureXML迭代查询语法,您也可以使用标准的XPath查询语言。以下是使用XPath查询所有球员的方法
[rootXML iterateWithRootXPath:@"//player" usingBlock: ^(RXMLElement *player) {
NSLog(@"Player: %@ (#%@)", [player child:@"name"], [player attribute:@"number"]);
}];
而且,记住,您也可以使用XPath测试属性。以下是找到编号为#5的球员的方法
[rootXML iterateWithRootXPath:@"//player[@number='5']" usingBlock: ^(RXMLElement *player) {
NSLog(@"Player #5: %@", [player child:@"name"]);
}];
请注意,您只能从文档根使用XPath,而不会影响您拥有的RXMLElement。如果您有一个派生RXMLElement,您仍然可以从文档根开始构建。如果您不了解XPath,可以使用这个方便的指南。
大多数方法支持命名空间,但是迭代时不支持。如果您想要为此类操作使用命名空间,请手动使用-childe方法。在指定命名空间时,请确保指定命名空间URI,而不是前缀。例如,如果您的XML看起来像这样
<team xmlns:sport="*" sport:year="2011" sport:name="New York Mets">
...
</team>
您将使用以下方式访问属性
NSLog(@"Team Name: %@", [e attribute:@"name" inNamespace:@"*"]);
RaptureXML可以轻松集成到RubyMotion中!以下是如何做。
您可以通过阅读项目中的单元测试来查看RaptureXML的全部用法。这不仅会向您展示所有代码,您还会知道它确实能工作!(您可以通过按Command-U在XCode中运行单元测试)
RaptureXML是由Rapture In Venice的John Blanco[email protected]创建的,因为他厌倦了使用用于iPhone开发的复杂XML解决方案。如果您喜欢这段代码或需要iOS顾问,请通过我的网站Rapture In Venice与我联系。