1

我有一些看起来像这样的 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标签数量,对于第一个info具有Plain Bagel.

就像我说的那样,我正在为 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?

我在这里先向您的帮助表示感谢。

4

1 回答 1

1

问题是您使用的是 HTML 解析器而不是 XML 解析器。info从 HTML 的角度来看,在打开和关闭标记之间有七个元素:

  • 一些文本(换行符和空格)
  • 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),您将不会处理打开和关闭标记之间的随机字符。

于 2015-03-01T00:55:15.080 回答