在 Swift 中创建 JSON 对象图的简单 XML 解析器

XML处理器

一个简单的 XML 解析器,可在 Swift 中创建 JSON 对象图。

例子

将 XML 字符串解析为对象图很简单:

let data = "<root><node>value</node></root>".data(using: .utf8)!

let processor = XMLProcessor()
if let object = processor.parse(data: data) {
  if let root = object["root"] as? Dictionary<String,Any> {
    // do something with root dictionary
  }
}

加工

为了处理 XML 和 JavaScript 对象 (JSON) 之间的差异,对 XML 进行了一些处理。

注意:不要假设对象字典中键的顺序与它们在 XML 中出现的顺序相同。处理期间不保留任何顺序(与 JSON 解析一样)。

如果 XML 有多个同名节点,它们将被放入一个数组中。例如,以下 XML:

<root>
	<metadata>Example</metadata>
	<entry>
		<title>First</title>
	</entry>
	<entry>
		<title>Second</title>
	</entry>
</root>		

会产生:

{
	"root": {
		"metadata": "Example",
		"entry": [
			{
				"title": "First"
			},
			{
				"title": "Second"
			}
		]
	}
}

在评估结果时,您可以使用 Swift 的类型强制转换。使用上面的示例,root["entry"] as? Array<Any>将返回一个值。

节点的属性存储在具有“$attrs”键的同级对象中。选择美元符号是因为它是一个无效的 XML 节点名称,但却是一个有效的 JavaScript 属性名称。这使得使用路径更容易访问。

例如,这个 XML:

<root>
	<node first="1" second="2" third="3">value</node>
</root>

产生:

{
	"root" : {
		"node" : "value",
		"node$attrs" : {
			"first" : "1",
			"second" : "2",
			"third" : "3"
		}
	}
}

请注意,这两个处理步骤在某些情况下可以组合。一个例子是多个链接节点,只有属性:

<root>
	<link first="abc" second="def" />
	<link first="hij" second="klm" />
</root>

只会产生属性字典:

{
	"root" : {
		"link$attrs" : [
			{
				"first" : "abc",
				"second" : "def"
			},
			{
				"first" : "hij",
				"second" : "klm"
			}
		]
	}
}

另请注意,不属于节点的文本将被忽略。例如:

<root>
	text
	<node>value</node>
</root>

结果:

{
	"root" : {
		"node" : "value"
	}
}

此功能应该足以解析从分层数据生成的 XML,例如由 WordPress 帖子数据库生成的 RSS 提要。

样本

SwiftUI 中的一个示例应用程序展示了如何XMLProcessor使用它来读取 Atom RSS 提要并使用它来创建使用Text提要中的 Markdown 生成的视图。

GitHub

查看 Github