用 Hpple 解析 Xcode 中的 xml
Parse xml in Xcode with Hpple
我有一些 xml 看起来像这样:
<menu>
<day name="monday">
<meal name="BREAKFAST">
<counter name="Bread">
<dish>
<name>Plain Bagel
<info name="Plain Bagel">
<serving>1 Serving (90g)</serving>
<calories>200</calories>
<caloriesFromFat>50</caloriesFromFat>
</info>
</name>
</dish>
<dish>
<name>Applesauce Coffee Cake
<info name="Applesauce Coffee Cake">
<serving>1 Slice-Cut 12 (121g)</serving>
<calories>374</calories>
<caloriesFromFat>104</caloriesFromFat>
</info>
</name>
</dish>
</counter>
</meal>
</day>
</menu>
现在我正在尝试获取 info
标签下的标签数量,对于具有 Plain Bagel
属性的第一个 info
标签来说应该是三个。
就像我说的,我正在为 iOS 使用 Hpple 解析器。这是我所拥有和正在尝试但无法完全正常工作的东西。
- (void)getData:(NSData*)factData {
TFHpple *Parser = [TFHpple hppleWithHTMLData:factData];
NSString *XpathQueryString = @"//day[@name='monday']/meal[@name='BREAKFAST']/counter[@name='Bread']/dish/name/info[@name='Plain Bagel']";
NSArray *Nodes = [Parser searchWithXPathQuery:XpathQueryString];
NSInteger count = Nodes.count;
NSLog(@"count: %ld", count);
for (TFHppleElement *element in Nodes) {
NSLog(@"count inside: %ld", element.children.count);
}
}
第一个计数给出 1。这是正确的,但内部计数给出 7,这是我感到困惑的地方。并且不确定为什么会这样。进入 info
标签后,我想遍历每个标签、服务、卡路里和来自脂肪的卡路里,并获取每个标签文本。但我不确定为什么它给出 7?
提前感谢您的帮助。
问题是您使用的是 HTML 解析器,而不是 XML 解析器。从 HTML 的角度来看,info
开始和结束标记之间有七个元素:
- 一些文本(换行符和空格)
serving
标签
- 一些文本(换行符和空格)
calories
标签
- 一些文本(换行符和空格)
caloriesFromFat
标签
- 一些文本(换行符和空格)
如果您遍历 children
个对象,您会准确地看到这一点。
如果您只需要与标签关联的条目,您可以检查节点是否有自己的子节点:
TFHpple *parser = [TFHpple hppleWithXMLData:factData];
NSString *xpathQueryString = @"//day[@name='monday']/meal[@name='BREAKFAST']/counter[@name='Bread']/dish/name/info[@name='Plain Bagel']";
NSArray *nodes = [parser searchWithXPathQuery:xpathQueryString];
for (TFHppleElement *element in nodes) {
for (TFHppleElement *child in element.children) {
if (child.children.count > 0) { // see if the child, itself, has children
NSLog(@" %@: '%@'", child.tagName, child.content);
}
}
}
或者您可以使用谓词:
TFHpple *parser = [TFHpple hppleWithXMLData:factData];
NSString *xpathQueryString = @"//day[@name='monday']/meal[@name='BREAKFAST']/counter[@name='Bread']/dish/name/info[@name='Plain Bagel']";
NSArray *nodes = [parser searchWithXPathQuery:xpathQueryString];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(TFHppleElement *node, NSDictionary *bindings) {
return node.children.count > 0;
}];
for (TFHppleElement *element in nodes) {
NSArray *filteredNodes = [element.children filteredArrayUsingPredicate:predicate];
for (TFHppleElement *child in filteredNodes) {
NSLog(@" %@: '%@'", child.tagName, child.content);
}
}
如果您使用的是正确的 XML 解析器(例如 NSXMLParser
),您就不会处理开始标签和结束标签之间的随机字符。
我有一些 xml 看起来像这样:
<menu>
<day name="monday">
<meal name="BREAKFAST">
<counter name="Bread">
<dish>
<name>Plain Bagel
<info name="Plain Bagel">
<serving>1 Serving (90g)</serving>
<calories>200</calories>
<caloriesFromFat>50</caloriesFromFat>
</info>
</name>
</dish>
<dish>
<name>Applesauce Coffee Cake
<info name="Applesauce Coffee Cake">
<serving>1 Slice-Cut 12 (121g)</serving>
<calories>374</calories>
<caloriesFromFat>104</caloriesFromFat>
</info>
</name>
</dish>
</counter>
</meal>
</day>
</menu>
现在我正在尝试获取 info
标签下的标签数量,对于具有 Plain Bagel
属性的第一个 info
标签来说应该是三个。
就像我说的,我正在为 iOS 使用 Hpple 解析器。这是我所拥有和正在尝试但无法完全正常工作的东西。
- (void)getData:(NSData*)factData {
TFHpple *Parser = [TFHpple hppleWithHTMLData:factData];
NSString *XpathQueryString = @"//day[@name='monday']/meal[@name='BREAKFAST']/counter[@name='Bread']/dish/name/info[@name='Plain Bagel']";
NSArray *Nodes = [Parser searchWithXPathQuery:XpathQueryString];
NSInteger count = Nodes.count;
NSLog(@"count: %ld", count);
for (TFHppleElement *element in Nodes) {
NSLog(@"count inside: %ld", element.children.count);
}
}
第一个计数给出 1。这是正确的,但内部计数给出 7,这是我感到困惑的地方。并且不确定为什么会这样。进入 info
标签后,我想遍历每个标签、服务、卡路里和来自脂肪的卡路里,并获取每个标签文本。但我不确定为什么它给出 7?
提前感谢您的帮助。
问题是您使用的是 HTML 解析器,而不是 XML 解析器。从 HTML 的角度来看,info
开始和结束标记之间有七个元素:
- 一些文本(换行符和空格)
serving
标签- 一些文本(换行符和空格)
calories
标签- 一些文本(换行符和空格)
caloriesFromFat
标签- 一些文本(换行符和空格)
如果您遍历 children
个对象,您会准确地看到这一点。
如果您只需要与标签关联的条目,您可以检查节点是否有自己的子节点:
TFHpple *parser = [TFHpple hppleWithXMLData:factData];
NSString *xpathQueryString = @"//day[@name='monday']/meal[@name='BREAKFAST']/counter[@name='Bread']/dish/name/info[@name='Plain Bagel']";
NSArray *nodes = [parser searchWithXPathQuery:xpathQueryString];
for (TFHppleElement *element in nodes) {
for (TFHppleElement *child in element.children) {
if (child.children.count > 0) { // see if the child, itself, has children
NSLog(@" %@: '%@'", child.tagName, child.content);
}
}
}
或者您可以使用谓词:
TFHpple *parser = [TFHpple hppleWithXMLData:factData];
NSString *xpathQueryString = @"//day[@name='monday']/meal[@name='BREAKFAST']/counter[@name='Bread']/dish/name/info[@name='Plain Bagel']";
NSArray *nodes = [parser searchWithXPathQuery:xpathQueryString];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(TFHppleElement *node, NSDictionary *bindings) {
return node.children.count > 0;
}];
for (TFHppleElement *element in nodes) {
NSArray *filteredNodes = [element.children filteredArrayUsingPredicate:predicate];
for (TFHppleElement *child in filteredNodes) {
NSLog(@" %@: '%@'", child.tagName, child.content);
}
}
如果您使用的是正确的 XML 解析器(例如 NSXMLParser
),您就不会处理开始标签和结束标签之间的随机字符。