我有一项作业需要阅读一些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/