Swift 使用 XMLDocument 處理 XML

Swift 有二種處理 XML 的方法,一種是 SAX,一種是 DOM。SAX 是使用 XMLParser,功能比較單純,早期就是用這個方法處理 XML 經文,這種方法不易處理複雜的資料。DOM 則是用 XMLDocument,比較能依前後文的不同來處理資料,本文是介紹後者的功能。

基本功能介紹

 

載入整個 XML 檔案

let doc = try? XMLDocument(contentsOf: file)

取出 root

let root = doc?.rootElement()

取出指定元素

let node = root?.elements(forName: "body")[0]

取出元素名稱

let name = node.name

取出元素全部屬性

let attribs = node.attributes
if attribs != nil {
    for att in attribs!  {
        ......
    }
}

取得指定屬性

if let attrib = node.attribute(forName: "id") {
    ......
}

取得屬性名稱

let attName = attrib.name!

取得屬性內容

let attVal = attrib.stringValue!

取出元素所有子節點

let nodes: [XMLNode]? = node.children
if nodes != nil {
    for node in nodes! {
        ......
    }
}

判斷節點的總類

if let node = node as? XMLElement {
    ......
}

if node.kind == XMLNode.Kind.element {
    ......
}

取得文字節點的內容

if node.kind == XMLNode.Kind.text {
    text = node.stringValue!
}

節點總類

XMLNode.kind [官方文件]

  • invalid : 指示在未指定有效種類的情況下創建的節點對象(由kind 方法返回)。

  • document : 指定文檔節點。

  • element : 指定元素節點。

  • attribute : 指定屬性節點

  • namespace : 指定名稱空間節點。

  • processingInstruction: 指定一個處理指令節點。

  • comment: 指定評論節點。

  • text: 指定文本節點。

  • DTDKind: 指定文檔類型聲明(DTD)節點。

  • entityDeclaration: 指定一個實體聲明節點。

  • attributeDeclaration: 指定屬性列表聲明節點。

  • elementDeclaration: 指定元素聲明節點。

  • notationDeclaration: 指定符號聲明節點。

範例程式

底下是依過去處理的習慣流程分析整個 XML 的程式

 

// 剖析 XML

// 初始化要傳入 URL, MyXMLPaser(URL)

// 執行 xml.parseXML() 傳回處理好的文字

 

class MyXMLParser {

    let file: URL

    init (_ file: URL) {

        self.file = file

    }

    

    // 分析整個 XML 文件

    func parseXML() -> String {

        var text = ""

        let doc = try? XMLDocument(contentsOf: file)

        let root = doc?.rootElement()

        let body = root?.elements(forName: "body")[0]

        if body != nil {

            text = parseNode(body!)

        }

        return text

    }

    

    // 分析一個節點

    func parseNode(_ node: XMLNode) -> String {

        var text = ""

        if let node = node as? XMLElement {

            // 處理標記元素

            let name = node.name

            switch name {

                case "name": text = tagName(node)

                case "company": text = tagComp(node)

                // ... 各種標記 ...

                default: text = tagDefault(node)

            }

        } else if node.kind == XMLNode.Kind.text {

            // 處理純文字

            text = "text: \(node.stringValue!)\n"

        }

        return text

    }

    

    // 分析子節點

    func parseChild (_ node: XMLNode) -> String {

        var text = ""

        let nodes: [XMLNode]? = node.children

        if nodes != nil {

            for node in nodes! {

                text += parseNode(node)

            }

        }

        return text

    }

    

    // MARK: 處理各個標記

    func tagName(_ node: XMLElement) -> String {

        var text = ""

        let name = node.name!

        text += "real name: \(name)\n"

        text += parseChild(node)

        return text

    }

    func tagComp(_ node: XMLElement) -> String {

        var text = ""

        let name = node.name!

        text += "Comp: \(name)\n"

        text += parseChild(node)

        return text

    }

    // 處理預設的標記

    func tagDefault(_ node: XMLElement) -> String {

        var text = ""

        // 取得標記名稱

        let name = node.name!

        text += "name: \(name)\n"

        // 取得全部屬性

        let attribs = node.attributes

        if attribs != nil {

            for att in attribs!  {

                let attName = att.name!

                let attVal = att.stringValue!

                text += "attrib: (\(attName):\(attVal))\n"

            }

        }

        // 取得特定屬性

        if let attId = node.attribute(forName: "id") {

            text += "Find ID: \(attId)\n"

            text += "Find ID name: \(attId.name!)\n"

            text += "Find ID attrib: \(attId.stringValue!)\n"

        }

        // 分析子節點

        text += parseChild(node)

        return text

    }

}

 

// 主程式

let xml = MyXMLParser(URL(fileURLWithPath: "sample.xml"))

let text = xml.parseXML()

print(text)

 

 

重要度:
文章分類:

回應

請問iOS APP 能用嗎??

試了一下好像要macOS才能用

如果不能的話好像只能透過第三方套件解析網站連結的html

謝謝

的確,若沒有提醒,我也沒注意到, XMLDocument 類別只有支援 macOS。

https://developer.apple.com/documentation/foundation/xmldocument

看來 iOS 是無法使用的。

 

發表新回應