arrays - 问题从 Swift 中的 xml 文件解码字符串

标签 arrays swift xml

我有一个 xml 文件,内容如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="array_ngontay_kq">
        <item>Bạn là người đáng tin cậy.</item>
        <item>Bạn là người có óc xét đoán. </item>
    </string-array>
</resources>

我用了HTMLReader获取此字符串数组,但我的输出如下所示:

Bạn là ngÆ°á»i Äáng tin cậy.
Bạn là ngÆ°á»i có óc xét Äoán.

这是我的代码:

let fileURL = Bundle.main.url(forResource: "BoiTay", withExtension: "xml")
        let xmlData = try! Data(contentsOf: fileURL!)
        let topic = "array_ngontay_kq"
        let document = HTMLDocument(data: xmlData, contentTypeHeader: "text/xml")
        for item in document.nodes(matchingSelector: "string-array[name='\(topic)'] item") {
                print(item.textContent)
            }

有没有办法解决这个问题,或者任何其他解决方案都可以在不使用 HTMLReader 的情况下解决这个问题。抱歉,我是 XMLParse 的新手,我在 Swift 中找不到关于此类 xml 文件的任何答案或教程。

最佳答案

首先,您最好检查一下您的BoiTay.xml 是否真的是UTF-8。我不熟悉越南语编码,但一些工具可能会生成使用 UTF-8 以外的其他编码的 XML,即使 xml header 声明 encoding="utf-8"

结果似乎是编码问题,而不是库或代码的错误。

请显示您的 xmlData 的十六进制转储,包括第一个 item 元素。

print(xmlData as NSData)

也许前 256 个字节就足够了。


顺便说一句,使用XMLParser 并不难。 (虽然这不是 super 容易。)

这是一个您可以在 Playground 中测试的示例。

import Foundation

class ResoucesParsingDelegate: NSObject, XMLParserDelegate {
    //Property to keey all `string-array`s by name
    var stringArrays: [String: [String]] = [:]

    var nameParsing: String? = nil
    var stringArrayParsing: [String]? = nil

    var currentText: String? = nil

    func parserDidStartDocument(_ parser: XMLParser) {
        print(#function)
    }

    func parserDidEndDocument(_ parser: XMLParser) {
        print(#function)
    }

    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
        print(#function, parseError)
    }

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        switch elementName {
        case "string-array":
            guard let name = attributeDict["name"] else {
                print("`string-array` element needs `name` attribute")
                return
            }
            //When you find `<string-array name="...">`, prepare a string array to keep items with its name
            nameParsing = name
            stringArrayParsing = []
        case "item":
            if stringArrayParsing == nil {
                print("invalid `item` element")
                return
            }
            //When you find `<item>`, prepare a string to keep the content text of the element
            currentText = ""
        //Prodess other elements
        //...
        default:
            print("Unknown element `\(elementName)`, ignored")
        }
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        switch elementName {
        case "string-array":
            if stringArrayParsing == nil || nameParsing == nil {
                print("invalid end tag `string-array`")
                return
            }
            //When you find `</string-array>`, add the current string array to `stringArrays` with its name
            stringArrays[nameParsing!] = stringArrayParsing!
            //Clear string array for next use
            stringArrayParsing = nil
        case "item":
            if stringArrayParsing == nil || currentText == nil {
                print("invalid end tag `item`")
                return
            }
            //When you find `</item>` add the content text to `stringArrayParsing`
            stringArrayParsing!.append(currentText!)
            //Clear content text for next use
            currentText = nil
        //Prodess other elements
        //...
        default:
            print("Unknown element `\(elementName)`, ignored")
        }
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        if currentText == nil {
            //Silently igonore characters while content string is not ready
            return
        }
        currentText! += string
    }
}

let xmlText = """
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="array_ngontay_kq">
        <item>Bạn là người đáng tin cậy.</item>
        <item>Bạn là người có óc xét đoán. </item>
    </string-array>
</resources>
"""

let xmlData = xmlText.data(using: .utf8)!

print(xmlData, xmlData as NSData)

let parser = XMLParser(data: xmlData)
let resoucesParsingDelegate = ResoucesParsingDelegate()
parser.delegate = resoucesParsingDelegate
parser.parse()

print(resoucesParsingDelegate.stringArrays)

输出:

246 bytes <3c3f786d 6c207665 7273696f 6e3d2231 2e302220 656e636f 64696e67 3d227574 662d3822 3f3e0a3c 7265736f 75726365 733e0a20 2020203c 73747269 6e672d61 72726179 206e616d 653d2261 72726179 5f6e676f 6e746179 5f6b7122 3e0a2020 20202020 20203c69 74656d3e 42e1baa1 6e206cc3 a0206e67 c6b0e1bb 9d6920c4 91c3a16e 67207469 6e2063e1 baad792e 3c2f6974 656d3e0a 20202020 20202020 3c697465 6d3e42e1 baa16e20 6cc3a020 6e67c6b0 e1bb9d69 2063c3b3 20c3b363 2078c3a9 7420c491 6fc3a16e 2e203c2f 6974656d 3e0a2020 20203c2f 73747269 6e672d61 72726179 3e0a3c2f 7265736f 75726365 733e>
parserDidStartDocument
Unknown element `resources`, ignored
Unknown element `resources`, ignored
parserDidEndDocument
["array_ngontay_kq": ["Bạn là người đáng tin cậy.", "Bạn là người có óc xét đoán. "]]

如果您使用 BoiTay.xml 的内容测试此代码并得到与 HTMLReader 类似的结果,则问题肯定是编码问题。

(如果您的实际 xml 比示例更复杂,您可能需要修改此代码。)

关于arrays - 问题从 Swift 中的 xml 文件解码字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52360224/

相关文章:

ios - Swift:视觉格式语言限制问题

c# - 如何在不替换所有属性的情况下编写 xml 属性?

arrays - 用于选择数组最小值的 VBA 代码

c++ - 简单 C++ 程序中的堆损坏

java - 数组索引越界 Java 生命游戏?

在 C 中将 Char 数组转换为 Long 错误

ios - 我可以让 subview 以其大小填充 View 吗?

swift - 如何使用 Swift 以编程方式引用 UILabel 强引用?

java - RecyclerView 滚动意外移动

xml - XML Schema 中的枚举定义是多余的