如何在 Swift 中将 XMLDocument 分解成更小的部分以便使用 XPath 进行处理?

How can I break up an XMLDocument into smaller parts for processing with XPath in Swift?

我有一份 XML 文档,我希望能够使用 XMLDocument DOM 解析器对其进行解析。我知道我可以使用 XPath 从文档中解析我感兴趣的部分。但是,我更希望能够使用 XPath 解析出某些元素并将这些元素本身视为文档。这里有一个简单的例子来说明。

import Foundation

class XMLDocumentExample {
    let xml = """
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Report xmlns="urn:com.conorgriffin/support/Report">
        <name>SpreadsheetGeneration</name>
        <reference-id>98ecd186d83301b418add9fb2006937f</reference-id>
        <common-id>F5S|242C11A2|5F9B870E</common-id>
        <customer>customer1</customer>
        <job-integration>
            <integration>load-data</integration>
            <id>675573850</id>
        </job-integration>
        <job-integration>
            <integration>generate-spreadsheet</integration>
            <id>136683540</id>
        </job-integration>
    </Report>
    """

    func parse() {
        do {
            let doc = try XMLDocument.init(xmlString: xml, options: [])
            let name = try doc.nodes(forXPath: "/Report/name")[0].stringValue
            let referenceID = try doc.nodes(forXPath: "/Report/reference-id")[0].stringValue
            let commonID = try doc.nodes(forXPath: "/Report/common-id")[0].stringValue
            let customer = try doc.nodes(forXPath: "/Report/customer")[0].stringValue
            let jobs = try doc.nodes(forXPath: "/Report/job-integration")
        } catch {
            print(error)
        }
    }
}

所以现在我从顶部元素Report的子节点中提取了一些字符串,我在变量jobs中还有一个XMLNode的数组。我想将此 jobs 变量传递给另一个函数并使用 XPath 获取每个作业的内部细节。我不想在 XPath 中包含 Report 元素,例如"/Report/job-integration/integration".

如何将每个 job-integration 节点视为一个独立的文档,以便我可以使用与 job-integration 元素相关的 XPath 对其进行解析,例如 "/integration""/id"?

我想通了,事实证明我快到了,但没有正确使用 XPath。

一旦我将 job-integration 节点从上面的初始代码传递到下面的函数中,我就可以在 XPath 查询的开头使用 . 字符来指示我想要一个相对于当前节点。

func build(node: XMLNode) -> JobIntegration {
        do {
            let integrationName = try node.nodes(forXPath: "./integration/text()")[0]
            let integrationId = try node.nodes(forXPath: "./id/text()")[0]
            return JobIntegration(id: integrationId, integration: integrationName)
        } catch {
            print(error)
        }
    }