Swift iOS - 解析时排除 root/parent 个元素 XML - NSXML
Swift iOS - Excluding root/parent elements when parsing XML - NSXML
我正在尝试使用 NSXMLParser 解析一个 XML RSS 提要并创建一个数组字典并在 table 视图中显示 - 这是有效的,但是我正在不匹配的结果。对于每个结果,我试图为每个 "item"(即每个 child)显示 "title" 和 "source" 元素 - 但因为 "title" 存在于 parent 节点它正在产生不匹配的结果。
是否可以指定只解析item下的元素?即类似 ["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
发生这种情况是因为 "title" 存在于根元素和 child 元素中,而源元素不存在?如果是这样,如何排除初始根元素?
我也在抓取其他值(例如 link)并且这些值确实匹配(即标题 1 将 return 与 Link1);大概是因为 "link" 也出现在 root?
如有任何帮助,我们将不胜感激!
非常感谢。
经过更多研究后,我设法使它正常工作。我重新编写了 XML 解析器,以便我明确指定从 "item" 节点开始解析;有效排除 root/parent 节点。重构的解析器看起来像:
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)
}
}
我正在尝试使用 NSXMLParser 解析一个 XML RSS 提要并创建一个数组字典并在 table 视图中显示 - 这是有效的,但是我正在不匹配的结果。对于每个结果,我试图为每个 "item"(即每个 child)显示 "title" 和 "source" 元素 - 但因为 "title" 存在于 parent 节点它正在产生不匹配的结果。
是否可以指定只解析item下的元素?即类似 ["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
发生这种情况是因为 "title" 存在于根元素和 child 元素中,而源元素不存在?如果是这样,如何排除初始根元素?
我也在抓取其他值(例如 link)并且这些值确实匹配(即标题 1 将 return 与 Link1);大概是因为 "link" 也出现在 root?
如有任何帮助,我们将不胜感激!
非常感谢。
经过更多研究后,我设法使它正常工作。我重新编写了 XML 解析器,以便我明确指定从 "item" 节点开始解析;有效排除 root/parent 节点。重构的解析器看起来像:
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)
}
}