【问题标题】:Parsing XML file in Swift在 Swift 中解析 XML 文件
【发布时间】:2014-07-29 02:39:15
【问题描述】:

我正在尝试使用 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 提要是科技史上的这一天 (http://feedpress.me/ThisDayInTechHistory),现在第一条新闻如下:

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 中的错误吗?或者我做错了什么?谢谢!

【问题讨论】:

    标签: ios xml swift


    【解决方案1】:

    你的猜测是正确的! NSXMLParser 假定字符串已经被转义,并且会遇到字符问题,包括><'&\

    要对字符串进行全局替换,可以使用NSString 方法stringByReplacingOccurrencesOfString,如下所示:

    let xml = "<desciption>Here's a malformed XML string. Ain't it ugly?</description>"
    xml.stringByReplacingOccurrencesOfString("'", withString: "&quot;")
    

    返回:

    "<desciption>Here&quot;s a malformed XML string. Ain&quot;t it ugly?</description>"
    

    【讨论】:

    • 感谢您的帮助,但我不确定我的猜测是否正确。我做了一个测试,发现这确实是返回的内容,并且标题分为标题和描述!我改进了上面显示的代码。
    • 你的意思是我先将 XML 加载到 String 中,在传递给 NSXMLParser 之前替换所有出现的地方?问题是加载整个 XML 文件并替换所有匹配项需要 10 秒,而且 xml.stringByReplacingOccurrencesOfString("'", withString: """) 似乎没有正确替换,输出已损坏。
    【解决方案2】:

    我发现了问题。获取元素“item”后,所有包含的“title”或“description”等元素都可以多次出现!所以“IBM的第一台台式电脑”会被拆分成2个标题,我们需要把它们组合成一些变量,只有元素结束时才构造结果。

    所以新代码将像这样工作:

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

    这行得通!

    【讨论】:

      【解决方案3】:

      Lim Thye Chean 的回答是正确的,但这是您代码中的问题:

      foundTitle = false

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

      恕我直言,最好的解决方案是使用这三种委托方法:

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

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

      3) 只有当解析器didEndElement "title" 时,我们才应该假设我们已经完成了"title" String。所以在这里我们应该说foundTitle = false,也在这里你应该说println(entryTitle)

      我希望这会有所帮助。我在使用 XMLParser 时遇到了很多困难,所以我写了一个简短的教程来了解它是如何工作的: https://medium.com/@lucascerro/understanding-nsxmlparser-in-swift-xcode-6-3-1-7c96ff6c65bc

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-14
        • 2017-06-06
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 2017-12-22
        相关资源
        最近更新 更多