2015-03-01 4 views
1

У меня есть XML, который выглядит следующим образом:Анализировать XML в Xcode с Hpple

<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.

Как я уже сказал, я использую парсер Hpple для iOS. Вот что я имею и пытаюсь, но не могу заставить его работать.

- (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?

Спасибо за помощь заранее.

+0

Используйте RaptureXML. Его супер простой и лучший XML-парсер там. –

ответ

1

Проблема в том, что вы используете парсер 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), вы не будете разбирать случайные символы между ярлыками open и close.

+0

Спасибо, есть способ удалить символы и пробелы новой строки, прежде чем разбирать его? – iqueqiorio

+0

Я собирался сделать что-то вроде 'if (element! = Nil) {', а затем NSLog внутри и посмотреть, зарегистрировано ли он 3 раза, но все равно 7, как я могу проверить, является ли этот элемент '\ n' – iqueqiorio

+0

You может либо посмотреть на «tagName», либо на количество дочерних дочерних элементов (я сделал последнее, выше). Честно говоря, я, вероятно, вообще не буду использовать Hpple, а скорее использую 'NSXMLParser'. – Rob