使用 XMLParser 在 Swift 中使用实体解析 XML

Parsing XML with entities in Swift with XMLParser

提问人:Julian 提问时间:6/21/2017 最后编辑:Julian 更新时间:6/22/2017 访问量:1159

问:

在 Swift 中使用 XMLParser 处理文档时,有没有办法扩展 XML 实体?我在 API 中没有看到任何东西,但我发现很难相信这是一个异国情调的要求。

如果直接从 Swift 使用 libxml2 API,则可以做到这一点,该库通过字符回调提供扩展实体,就好像它以内联方式出现一样。

这是我的示例代码:

let xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
    "<!DOCTYPE simple [" +
    "<!ENTITY e \"entity\">" +
    "]>" +
    "<root><val>&e;</val></root>"

class ParserDelegate : NSObject, XMLParserDelegate {
    var entities = [String:String?]()
    var text: String?

    func parser(_ parser: XMLParser, foundInternalEntityDeclarationWithName name: String, value: String?) {
        self.entities[name] = value
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        text = text == nil ? string : self.text! + string
    }
}

let delegate = ParserDelegate()

let parser = XMLParser(data: xml.data(using: String.Encoding.utf8)!)
parser.delegate = delegate


parser.parse()

if let text = delegate.text {
    print("found text:" + text)
}

delegate.entities.forEach() {
    (entry) in let (key, val) = entry
    print(key + ": " + (val ?? "<nil>"))
}

运行此操作时,永远不会打印“找到的文本”,因为从不调用,这可以通过设置断点进行验证。func parser(_ parser: XMLParser, foundCharacters string: String)

输出很简单:

e: entity

我尝试查看委托上的各种方法,但我没有看到任何相关内容。该方法看起来很接近,但这些是内部实体,实现它不会产生有趣的结果。public func parser(_ parser: XMLParser, resolveExternalEntityName name: String, systemID: String?) -> Data?

编辑

看起来这确实是解析器的一个限制,可以追溯到很多年前。

我可以在 stackoverflow 上找到 2009 年的问题:

我在 2017 年 5 月的 Open Radar 上找到了这个项目:

libxml2 库上有一些关于实体的评论,这些注释指出了实体带来的一些挑战,这可能有助于解释为什么 (NS)XMLParser 的行为是这样的。

Swift Swift3 XML 解析

评论

0赞 rmaddy 6/22/2017
我也无法让它工作。我什至发现如此旧的线程(使用 Objective-C 和 NSXMLParser)报告了同样的问题。如果在周围添加任何其他文本,则会报告该文本。如果更改为其他内容,则会收到有关未解析实体的预期错误。但出于某种原因,根本不会发送已解析的实体(或任何其他委托)。我会将此作为错误报告给Apple。&e;&e;XMLParserfoundCharacters
0赞 Julian 6/22/2017
感谢您的反馈,如果我得到的唯一回复与您的回复相似,我会这样做。

答: 暂无答案