我有一项作业需要阅读一些RSS提要并建立用户个人资料等。

我的问题是,当我从基础上使用XMLParser时,会遇到“操作无法完成。(NSXMLParserErrorDomain错误9。)”

我检查了文档,看来我有invalidCharacterError。我认为我的代码没有问题,因为它适用于其他网址供稿。那么我该怎么做才能克服这个问题呢?

这是网址:http://halley.exp.sis.pitt.edu/comet/utils/_rss.jsp?v=bookmark&user_id=3600

附言此供稿包含CDATA,因此我注释掉了标题和描述,但应显示日期,但仍显示该错误。因此,我担心的是,在解析xml期间,它遇到了任何无效字符并报告了错误。反正要解决吗?我必须使用此网址。

和一些相关的代码在这里:

func parseFeed(url: String, completionHandler: (([RSSItem]) -> Void)?)
{
    self.parserCompletionHandler = completionHandler

    let request = URLRequest(url: URL(string: url)!)
    let urlSession = URLSession.shared
    let task = urlSession.dataTask(with: request) { (data, response, error) in
        guard let data = data else {
            if let error = error {
                print(error.localizedDescription)
            }

            return
        }

        /// parse our xml data
        let parser = XMLParser(data: data)
        parser.delegate = self
        parser.parse()
    }

    task.resume()
}

// MARK: - XML Parser Delegate

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:])
{
    currentElement = elementName
    if currentElement == "item" {
        currentTitle = ""
        currentDescription = ""
        currentPubDate = ""
    }
}

func parser(_ parser: XMLParser, foundCharacters string: String)
{
    switch currentElement {
//        case "title": currentTitle += string
//        case "description" : currentDescription += string
        case "pubDate" : currentPubDate += string
        default: break
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
    if elementName == "item" {
        let rssItem = RSSItem(title: currentTitle, description: currentDescription, pubDate: currentPubDate)
        self.rssItems.append(rssItem)
    }
}

func parserDidEndDocument(_ parser: XMLParser) {
    parserCompletionHandler?(rssItems)
}

func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error)
{
    print(parseError.localizedDescription)
}

最佳答案

我在显示的URL的响应中的CDATA元素之一中发现了无效的字节0xFC。

这在声明encoding="UTF-8"的文档中作为UTF-8字节无效。

您最好将URL告知服务器工程师,RSS feed的XML无效。

如果需要使用这种格式错误的XML,则需要将其转换为有效的UTF-8数据。

0xFC在ISO-LATIN-1中表示ü,因此您可以编写如下内容。

func parseFeed(url: String, completionHandler: (([RSSItem]) -> Void)?)
{
    self.parserCompletionHandler = completionHandler

    let request = URLRequest(url: URL(string: url)!)
    let urlSession = URLSession.shared
    let task = urlSession.dataTask(with: request) { (data, response, error) in
        guard var data = data else { //###<-- `var` here
            if let error = error {
                print(error.localizedDescription)
            }

            return
        }

        //### When the input `data` cannot be decoded as a UTF-8 String,
        if String(data: data, encoding: .utf8) == nil {
            //Interpret the data as an ISO-LATIN-1 String,
            let isoLatin1 = String(data: data, encoding: .isoLatin1)!
            //And re-encode it as a valid UTF-8
            data = isoLatin1.data(using: .utf8)!
        }

        /// parse our xml data
        let parser = XMLParser(data: data)
        parser.delegate = self
        parser.parse()
    }

    task.resume()
}


如果您需要使用其他编码,则问题将更加困难,因为很难正确估计文本编码。



您可能需要实现func parser(_ parser: XMLParser, foundCDATA CDATABlock: Data),但这似乎是另一个问题。

关于swift - 如何在iOS Swift中解决XMLParser.ErrorCode.invalidCharacterError?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52489760/

10-09 20:52