Ios 用Swift解析XML文件

Ios 用Swift解析XML文件,ios,xml,swift,Ios,Xml,Swift,我正在尝试使用NSXMLParser解析XML文件。起初一切似乎都很好,但内容结果似乎被截断了,得到了一些奇怪的结果 func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) { if elemen

我正在尝试使用NSXMLParser解析XML文件。起初一切似乎都很好,但内容结果似乎被截断了,得到了一些奇怪的结果

func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
    if elementName == "title" {
        foundTitle = true
    }

    if elementName == "description" {
        foundDescription = true
    }
}

func parser(parser: NSXMLParser!, foundCharacters string: String!) {
    if (foundItem) {
        if foundTitle {
            println("Title: \(string)")
            foundTitle = false
        }
        else if foundDescription {
            println("Description: \(string)")
            foundDescription = false
        }
    }
}
我正在测试的RSS源是科技史()中的这一天,现在第一条新闻有以下内容:

Title: IBM’s First Desktop Computer
Description: IBM introduces their System/23 Datamaster desktop computer...
但是对于我的测试结果,这是我得到的:

Title: IBM
Description: ’s First Desktop Computer
Description: July 28, 1981 IBM introduces their System/23 Datamaster desktop computer...

请注意,标题在第一个“后被截断,并成为描述!”!这是NSXMLParser中的错误吗?或者我做错了什么?谢谢

你的猜测是正确的!NSXMLParser假定字符串已经转义,并且会遇到字符问题,包括
您的猜测是正确的!NSXMLParser假定字符串已经转义,并将遇到字符问题,包括
我发现了问题。获取元素“item”后,所有包含的元素如“title”或“description”都可以多次出现!因此,“IBM的第一台台式计算机”将被分成两个标题,我们需要将它们组合成一些变量,并且只在元素结束时构造结果

因此,新代码的工作原理如下:

func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
    element = elementName

    if element == "item" {
        isItem = true
        titleText = ""
        ...
    }
}

// Get element text

func parser(parser: NSXMLParser!, foundCharacters string: String!) {
    if isItem {
        if element == "title" {
            titleText += string
        }

        ...
    }
}

// Construct HTML when element end

func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
    if elementName == "item" {
        html += "<b>\(titleText)</b>"
        ...
    }
}
func解析器(解析器:NSXMLParser!、didStartElement元素名称:String!、namespaceURI:String!、qualifiedName qName:String!、attributes attributeDict:[NSObject:AnyObject]!){
element=elementName
如果元素==“项”{
isItem=true
titleText=“”
...
}
}
//获取元素文本
func解析器(解析器:NSXMLParser!,foundCharacters string:string!){
如果isItem{
如果元素==“标题”{
titleText+=字符串
}
...
}
}
//在元素结束时构造HTML
func解析器(解析器:NSXMLParser!、didEndElement元素名称:String!、namespaceURI:String!、qualifiedName qName:String!){
如果elementName==“项”{
html+=“\(标题文本)”
...
}
}

这管用

我发现了这个问题。获取元素“item”后,所有包含的元素如“title”或“description”都可以多次出现!因此,“IBM的第一台台式计算机”将被分成两个标题,我们需要将它们组合成一些变量,并且只在元素结束时构造结果

因此,新代码的工作原理如下:

func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
    element = elementName

    if element == "item" {
        isItem = true
        titleText = ""
        ...
    }
}

// Get element text

func parser(parser: NSXMLParser!, foundCharacters string: String!) {
    if isItem {
        if element == "title" {
            titleText += string
        }

        ...
    }
}

// Construct HTML when element end

func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
    if elementName == "item" {
        html += "<b>\(titleText)</b>"
        ...
    }
}
func解析器(解析器:NSXMLParser!、didStartElement元素名称:String!、namespaceURI:String!、qualifiedName qName:String!、attributes attributeDict:[NSObject:AnyObject]!){
element=elementName
如果元素==“项”{
isItem=true
titleText=“”
...
}
}
//获取元素文本
func解析器(解析器:NSXMLParser!,foundCharacters string:string!){
如果isItem{
如果元素==“标题”{
titleText+=字符串
}
...
}
}
//在元素结束时构造HTML
func解析器(解析器:NSXMLParser!、didEndElement元素名称:String!、namespaceURI:String!、qualifiedName qName:String!){
如果elementName==“项”{
html+=“\(标题文本)”
...
}
}

这管用

Lim Thye Chean的答案是正确的,但您的代码中有一个问题:

foundTitle=false

您可以看到,
foundCharacters
在它遇到的第一个
处停止。然后设置
foundTitle=false
。因此,当
foundCharacters
继续查找它们时,字符串的其余部分将被忽略(因为
foundTitle=false

最好的解决方案IMHO是使用以下三种委托方法:

1) 在
didStartelement
中,您应该设置一个临时变量,例如
var entryTitle=String()
(因此每次解析器
didStartelement“title”
时,我们都会清除这个字符串)

2)
foundCharacters
被多次调用,在许多“不常见”字符处停止。我们需要将找到的每个字符串附加到临时变量中。因此,在
foundCharacters
中,我们应该说:
entryTitle+=string
(将解析器单独找到的字符串的所有比特附加到我们的变量中)

3) 只有当解析器
didEndElement“title”
时,我们才应该假定
的“title”字符串已完成。所以在这里我们应该说
foundTitle=false
,在这里你应该
println(entryTitle)

我希望这有帮助。我一直在努力学习XMLParser,因此我编写了一个简短的教程来了解它的工作原理:
Lim Thye Chean的答案是正确的,但代码中有一个问题:

foundTitle=false

您可以看到,
foundCharacters
在它遇到的第一个
处停止。然后设置
foundTitle=false
。因此,当
foundCharacters
继续查找它们时,字符串的其余部分将被忽略(因为
foundTitle=false

最好的解决方案IMHO是使用以下三种委托方法:

1) 在
didStartelement
中,您应该设置一个临时变量,例如
var entryTitle=String()
(因此每次解析器
didStartelement“title”
时,我们都会清除这个字符串)

2)
foundCharacters
被多次调用,在许多“不常见”字符处停止。我们需要将找到的每个字符串附加到临时变量中。因此,在
foundCharacters
中,我们应该说:
entryTitle+=string
(将解析器单独找到的字符串的所有比特附加到我们的变量中)

3) 只有当解析器
didEndElement“title”
时,我们才应该假定
的“title”字符串已完成。所以在这里我们应该说
foundTitle=false
,在这里你应该
println(entryTitle)

我希望这有帮助。我一直在努力学习XMLParser,因此我编写了一个简短的教程来了解它的工作原理:

谢谢您的帮助
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
    element = elementName

    if element == "item" {
        isItem = true
        titleText = ""
        ...
    }
}

// Get element text

func parser(parser: NSXMLParser!, foundCharacters string: String!) {
    if isItem {
        if element == "title" {
            titleText += string
        }

        ...
    }
}

// Construct HTML when element end

func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
    if elementName == "item" {
        html += "<b>\(titleText)</b>"
        ...
    }
}