2016-02-07 5 views
1

Я пытаюсь проанализировать XML-канал RSS с помощью NSXMLParser и создавать словарь массивов и отображать в виде таблицы, который работает, однако я получаю несоответствующие результаты. Для каждого результата я пытаюсь показать элементы «title» и «source» для каждого «элемента» (т. Е. Для каждого дочернего элемента), но поскольку в родительском узле существует «title», он создает несоответствие результатов.Swift iOS - Исключение корневых/родительских элементов при разборе XML - NSXML

Можно ли указать только элементы анализа под элементом? например, ["items"] ["title"]? Вот пример структуры я разборе:

<rss xmlns:atom="example" xmlns:dc="http://example" version="2.0"> 
<channel> 
<title>Main title</title> 
<link>http://main-site.com/xmltest</link> 
<description>Main description</description> 
<pubDate>Sun, 07 Feb 2016 10:41:05 +0000</pubDate> 
    <item> 
     <title>Title 1</title> 
     <link>https://item1.com</link> 
     <description>Description1</description> 
     <pubDate>Date1</pubDate> 
     <source>Source1</source> 
    </item> 
    <item> 
     <title>Title 2</title> 
     <link>https://item2.com</link> 
     <description>Description2</description> 
     <pubDate>Date2</pubDate> 
     <source>Source2</source> 
    </item> 
    <item> 
     <title>Title 3</title> 
     <link>https://item3.com</link> 
     <description>Description3</description> 
     <pubDate>Date3</pubDate> 
     <source>Source3</source> 
    </item> 
</channel> 

Код парсер NSXML у меня есть:

func parser(parser: NSXMLParser, 
    didStartElement elementName: String, 
    namespaceURI: String?, 
    qualifiedName: String?, 
    attributes attributeDict: [String : String]){ 
     if elementName == "title"{ 
      entryTitle = String() 
      currentParsedElement = "title" 
     } 
     if elementName == "description"{ 
      entryDescription = String() 
      currentParsedElement = "description" 
     } 
     if elementName == "link"{ 
      entryLink = String() 
      currentParsedElement = "link" 
     } 
     if elementName == "source"{ 
      entrySource = String() 
      currentParsedElement = "source" 
     } 
     if elementName == "pubDate"{ 
      entryDate = String() 
      currentParsedElement = "pubDate" 
     } 
} 

func parser(parser: NSXMLParser, 
    foundCharacters string: String){ 
     if currentParsedElement == "title"{ 
      self.entryTitle = entryTitle + string 
     } 
     if currentParsedElement == "description"{ 
      self.entryDescription = entryDescription + string 
     } 
     if currentParsedElement == "link"{ 
      self.entryLink = entryLink + string 
     } 
     if currentParsedElement == "source"{ 
      self.entrySource = entrySource + string 
     } 
     if currentParsedElement == "pubDate"{ 
      self.entryDate = entryDate + string 
     } 

} 

func parser(parser: NSXMLParser, 
    didEndElement elementName: String, 
    namespaceURI: String?, 
    qualifiedName qName: String?){ 
     if elementName == "title"{ 
      entryDictionary["title"] = entryTitle 
     } 
     if elementName == "link"{ 
      entryDictionary["link"] = entryLink 
     } 
     if elementName == "description"{ 
      entryDictionary["description"] = entryDescription 
     } 
     if elementName == "source"{ 
      entryDictionary["source"] = entrySource 
     } 
     if elementName == "pubDate"{ 
      entryDictionary["pubDate"] = entryDate 
      entriesArray.append(entryDictionary) 
     } 

} 

func parserDidEndDocument(parser: NSXMLParser){ 
    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     self.tableView.reloadData() 
    }) 
} 

Результаты, которые я получаю от этого:

  1. Основное название, (нет источника)
  2. Раздел 1, (без источника)
  3. Заголовок 2, Источник 1
  4. Название 3, Источник 2

Это происходит потому, что существует «название» в корневых и дочерних элементов, в то время как источник не делает? Если да, то как я могу исключить исходные корневые элементы?

Я также захватываю другие значения (такая ссылка), и эти значения соответствуют (т. Е. Название 1 будет возвращаться с помощью Link1); по-видимому, потому, что «ссылка» также появляется в корне?

Любая помощь будет оценена!

Большое спасибо.

ответ

0

После нескольких исследований мне удалось получить эту работу. Я повторно обработал синтаксический анализатор XML, чтобы я явно указал, чтобы начать синтаксический анализ с узла «item»; эффективно исключая корневые/родительские узлы. Анализируемый парсер выглядит так:

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) 
{ 
    element = elementName 
    if (elementName as NSString).isEqualToString("item") 
    { 
     elements = NSMutableDictionary() 
     elements = [:] 
     title1 = NSMutableString() 
     title1 = "" 
     source = NSMutableString() 
     source = "" 
     pubDate = NSMutableString() 
     pubDate = "" 
     link = NSMutableString() 
     link = "" 
    } 
} 

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) 
{ 
    if (elementName as NSString).isEqualToString("item") { 
     if !title1.isEqual(nil) { 
      elements.setObject(title1, forKey: "title") 
     } 
     if !source.isEqual(nil) { 
      elements.setObject(source, forKey: "source") 
     } 
     if !pubDate.isEqual(nil) { 
      elements.setObject(pubDate, forKey: "pubDate") 
     } 
     if !link.isEqual(nil) { 
      elements.setObject(link, forKey: "link") 
     } 
     posts.addObject(elements) 
    } 
} 

func parser(parser: NSXMLParser, foundCharacters string: String) 
{ 
    if element.isEqualToString("title") { 
     title1.appendString(string) 
    } else if element.isEqualToString("source") { 
     source.appendString(string) 
    } 
    else if element.isEqualToString("pubDate") { 
     pubDate.appendString(string) 
    } 
    else if element.isEqualToString("link"){ 
     link.appendString(string) 
    } 
} 
Смежные вопросы