Skip to Content

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)

 

 

回應

發表新回應

這個欄位的內容會保密,不會公開顯示。
  • 自動將網址與電子郵件地址轉變為連結。
  • 自動斷行和分段。
  • 可使用的 HTML 標籤:<a> <address> <b> <blockquote> <br> <caption> <center> <cite> <code> <dd> <del> <div> <dl> <dt> <em> <h1> <h2> <h3> <h4> <h5> <h6> <hr> <i> <img> <ins> <li> <ol> <p> <pre> <span> <strike> <strong> <sub> <sup> <table> <tbody> <td> <th> <tr> <u> <ul>
    Allowed Style properties: background, background-attachment, background-color, background-image, background-position, background-repeat, border, border-bottom, border-bottom-color, border-bottom-style, border-bottom-width, border-collapse, border-color, border-left, border-left-color, border-left-style, border-left-width, border-right, border-right-color, border-right-style, border-right-width, border-spacing, border-style, border-top, border-top-color, border-top-style, border-top-width, border-width, bottom, caption-side, clip, color, direction, empty-cells, font, font-family, font-size, font-size-adjust, font-stretch, font-style, font-variant, font-weight, height, left, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, margin, margin-bottom, margin-left, margin-right, margin-top, max-height, max-width, min-height, min-width, overflow, padding, padding-bottom, padding-left, padding-right, padding-top, right, table-layout, text-align, text-decoration, text-indent, text-transform, top, unicode-bidi, vertical-align, white-space, width, word-spacing, z-index

更多關於格式選項的資訊

CAPTCHA
驗證碼只有阿拉伯數字, 這是躲廣告用的, 麻煩你輸入了.
Image CAPTCHA
Enter the characters shown in the image.


story | about seo