Как решить XMLParser.ErrorCode.invalidCharacterError в IOS Swift? - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть домашнее задание, нужно прочитать некоторые RSS-каналы и создать профиль пользователя и т. Д.

Моя проблема в том, что когда я использую XMLParser из фонда, я столкнусь с «Операция не может быть завершена. (Ошибка NSXMLParserErrorDomain»)9.) "

Я проверил документацию, и кажется, что у меня есть invalidCharacterError.Я не думаю, что у моего кода есть проблема, так как он хорошо работает для других каналов.Так что я должен сделать, чтобы преодолеть эту проблему?

Вот URL: http://halley.exp.sis.pitt.edu/comet/utils/_rss.jsp?v=bookmark&user_id=3600

PS Этот канал содержит CDATA, поэтому я закомментирую заголовок и описание, но он должен отображать дату, но этопокажи эту ошибку.Поэтому я обеспокоен тем, что во время синтаксического анализа xml он обнаружил недопустимый символ и сообщил об ошибке.В любом случае, чтобы это исправить?Я должен использовать этот URL, хотя.

и некоторый связанный код здесь:

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)
}

1 Ответ

0 голосов
/ 25 сентября 2018

Я нашел недопустимый байт 0xFC внутри одного из элементов CDATA в ответе на указанный вами URL.

Это недопустимо как байт UTF-8 в документе, объявляющем encoding="UTF-8".

Вам лучше сообщить инженеру-серверу URL-адреса, что XML-канал RSS недействителен.

Если вам нужно работать с этим плохо сформированным 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), но, похоже, это другая проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...