(Kiss)XML xpath 和默认命名空间 [英] (Kiss)XML xpath and default namespace
问题描述
我正在处理一个需要解析一些 xml 的 iPhone 项目.xml 可能包含也可能不包含默认命名空间.我需要知道如何解析 xml,以防它使用默认命名空间.由于我需要同时读取写入的 xml,因此我倾向于使用 KissXML,但我愿意接受建议.
I am working on an iPhone project that needs to parse some xml. The xml may or may not include a default namespace. I need to know how to parse the xml in case it uses a default namespace. As I need to both read an write xml, I'm leaning towards using KissXML, but I'm open for suggestions.
这是我的代码:
NSString *content = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@"bookstore" ofType:@"xml"] encoding:NSUTF8StringEncoding error:nil];
DDXMLDocument *theDocument = [[DDXMLDocument alloc] initWithXMLString:content options:0 error:nil];
NSArray *results = [theDocument nodesForXPath:@"//book" error:nil];
NSLog(@"%d", [results count]);
它在这个 xml 上按预期工作:
It works as expected on this xml:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
</book>
</bookstore>
但是当 xml 有一个命名空间时,像这样,它停止工作:
But when the xml has a namespace, like this, it stops working:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore xmlns="[INSERT RANDOM NAMESPACE]">
<book category="COOKING">
<title lang="en">Everyday Italian</title>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
</book>
</bookstore>
当然,我可以只预处理字符串并删除 xmlns,尽管这感觉像是一种丑陋的 hack.处理这个问题的正确方法是什么?
Of course, I could just preprocess the string and remove the xmlns, though that feels like a sort of ugly hack. What is the proper way to handle this?
推荐答案
干净的方式:查询命名空间
可以使用两种XPath查询,一种是获取命名空间,然后注册;作为第二个查询,使用您已经拥有的包含名称空间的查询.我只能帮助您查询,但您似乎对命名空间以及如何在 KissXML 框架中注册它们非常熟悉:
The Clean Way: Querying for the Namespace
You can use two XPath queries, one to fetch the namespace, then register it; as second query use the one you already have including namespaces. I can only help you with the query, but it seems you're quite familiar with namespaces and how to register them in the KissXML framework:
namespace-uri(/*)
此表达式获取从文档根开始的所有子节点,根据 XML 定义,它是单个根元素,并返回其命名空间 uri.
This expression fetches all child nodes starting at the document root, which is per XML definition a single root element, and returns it's namespace uri.
似乎 KissXML 只支持 XPath 1.0.对于这个功能较弱的语言版本,您需要在每个轴步骤中使用通配符选择器并比较谓词内的本地名称(没有命名空间前缀):
It seems KissXML only supports XPath 1.0. With this less-capable language version, you need to use wildcard selectors at each axis step and compare the local name (without namespace prefix) inside the predicate:
//*[local-name(.) = 'book']
从 XPath 2.0 开始,您可以使用命名空间通配符进行查询,该通配符要短得多:
Starting from XPath 2.0, you could query using the namespace wildcard, which is much shorter:
//*:book
这篇关于(Kiss)XML xpath 和默认命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!