XMLParser在读取UTF8字符时遇到问题

时间:2017-01-02 05:13:57

标签: xml swift3

我正在尝试按如下方式解析XML

<CntyNtry>
    <EngNm>Virgin Islands (British)</EngNm>
    <FrNm>Vierges britanniques (les Îles)</FrNm>
    <A2Cd>VG</A2Cd>
    <A3Cd>VGB</A3Cd>
    <CtryNbr>92</CtryNbr>
</CntyNtry>

正如您所看到的,某些字母上有一些重音。

我尝试使用以下代码解析XML

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    if elementName == Element.getXMLRecordElementTagName() {
        stack.push(Element.newObject())
        record.removeAll(keepingCapacity: false)
    } else if Element.getXMLRecordAttributeElementTagName().contains(elementName) {
        stackKey.push(Element.getNSManagedObjectAttributeName(fromXMLRecordElementTagName: elementName))
    }
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
    let key = stackKey.pop()
    if key != nil {
        record[key!] = string
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == Element.getXMLRecordElementTagName() {
        Element.add(object: record)
        record.removeAll(keepingCapacity: false)
    }
}

如果有人需要其余代码的详细信息,请告诉我,但基本上记录[key!] = string应该能够读取UTF8字符。

当我测试单位代码上的数据时,我得到以下错误,其中字符串在重音字符串后未被读取。我已尝试使用重音的所有其他数据,这是同样的错误。

  

XCTAssertEqual失败:(“可选(”Vierges britanniques(les“)”)不等于(“Optional(”Vierges britanniques(lesÎles)“)”) -

我的单元测试代码是错误的吗?或者解析器有问题吗?

func testImportDataCnty() {
    Country.delete()
    XCTAssertTrue(Country.count() == 0)
    XCTAssertTrue(importerCnty.importData())
    XCTAssertTrue(Country.count() > 0)

    let kor = Country.get(id: ["VGB"])?[0] as! Country
    XCTAssertEqual(kor.englishName, country2["englishName"] as? String)
    XCTAssertEqual(kor.frenchName, country2["frenchName"] as? String)
    //Test failed on the above row.
    XCTAssertEqual(kor.alpha2Code, country2["alpha2Code"] as? String)
    XCTAssertEqual(kor.alpha3Code, country2["alpha3Code"] as? String)
    XCTAssertEqual(kor.countryNumber, Int16(country2["countryNumber"] as! Int))
}

2 个答案:

答案 0 :(得分:1)

您应该以HTML编码的形式在XML中存储任何特殊或外语字符。举个例子,当我需要为Ampersand编写XML时,我做了以下几点:

<name>Jones &amp; Jones</name>

在你的情况下,它应该是:

<FrNm>Vierges britanniques (les &Icirc;les)</FrNm>

请参阅this HTML encoding table.

答案 1 :(得分:0)

我通过更改我的代码解决了这个问题,如下所示。 如果字符串中有特殊字符,findcharacter解析器似乎多次读取字符串,所以我需要将它们全部附加。

func parser(_ parser: XMLParser, foundCharacters string: String) {
    let key = stackKey.peek()
    if key != nil {
        if record[key!] != nil {
            record[key!] = record[key!]! + string
        } else {
            record[key!] = string
        }
    }
}