美文网首页
Swift - 解析XML格式数据(分别使用KissXML)

Swift - 解析XML格式数据(分别使用KissXML)

作者: 小驴拉磨 | 来源:发表于2020-07-01 14:19 被阅读0次

使用KissXML(DDXML)

1、GitHub主页地址:https://github.com/robbiehanson/KissXML
2、在build phases -> Link Binary With Libraries中,点击“+”添加“libxml2.2.tbd”

添加“libxml2.2.tbdg
3、在build setting -> Header Search Paths里添加 ${SDK_DIR}/usr/include/libxml2
image.png
4、添加bridge.h头文件并设置到编译参数里
#import "DDXML.h"
#import "DDXMLElementAdditions.h"

5、开始解析(ViewController.swift)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let label:UILabel = UILabel(frame:CGRect(x: 100, y: 100, width: 300, height: 100));
            label.text = "输出结果在控制台"
            self.view.addSubview(label)
            //测试Swift调用Object的XML库功能
            testXML()
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    func testXML() {
        //获取xml文件路径
        let file = Bundle.main.path(forResource: "users", ofType: "xml")
        let url = URL(fileURLWithPath: file!)
        //获取xml文件内容
        let xmlData = try! Data(contentsOf: url)
         
        //构造XML文档
        let doc = try! DDXMLDocument(data: xmlData, options:0)
         
        //利用XPath来定位节点(XPath是XML语言中的定位语法,类似于数据库中的SQL功能)
        let users = try! doc.nodes(forXPath: "//User") as! [DDXMLElement]
        for user in users {
            let uid = user.attribute(forName: "id")!.stringValue
            //DDXMLElementAdditions提供了elementForName获取单个节点,不用获取数组了
            let uname = user.forName("name")!.stringValue
            //获取tel节点的子节点
            let telElement = user.forName("tel")! as DDXMLElement
            let mobile = (telElement.forName("mobile")! as DDXMLElement).stringValue
            let home = (telElement.forName("home")! as DDXMLElement).stringValue
            print("User: uid:\(uid!),uname:\(uname!),mobile:\(mobile!),home:\(home!)")
        }
    }
}

2,DDXML获取子元素:forName(name: String)与elements(forName: String)
forName(name: String) 是根据name取同名的子结点,如果有多个 ,就只取第一个。
elements(forName: String) 是把所有的同名子节点都返回。
比如把上面XML数据文件users.xml每个人都添加多个mobile节点:


image.png

如果想把所有的mobile节点都遍历出来,就要使用elements(forName: String)

//let mobile = (telElement.forName("mobile")! as DDXMLElement).stringValue
for element in telElement.elements(forName:"mobile"){
    let mobile = element.stringValue
    print("mobile:\(mobile!)")
}

3,扩展DDXML方便使用
使用 DDXML 的 elementForName 方法访问子节点时,要不断地拆箱装箱,如果节点层级深的话写起来就会比较麻烦。
这里对 DDXMLElement 类做了扩展,使其通过索引即可访问子节点。同时添加了个 attributeValue() 方法,便于获取属性值。

extension DDXMLElement {
    //通过索引获取子节点
    subscript(key: String) -> DDXMLElement {
        get {
            let r = self.forName(key)
            return r!
        }
    }
}

可以比较下原来的取值方式和现在的方式:

/********* 原始的 ****************/
let uid = user.attribute(forName: "id")!.stringValue
let uname = user.forName("name")!.stringValue
 
let telElement = user.forName("tel")! as DDXMLElement
let mobile = (telElement.forName("mobile")! as DDXMLElement).stringValue
let home = (telElement.forName("home")! as DDXMLElement).stringValue
 
print("User: uid:\(uid!),uname:\(uname!),mobile:\(mobile!),home:\(home!)")
 
/******** 扩展后的 *****************/
let uid = user.attribute(forName: "id")!.stringValue
let uname = user["name"].stringValue
 
let mobile = user["tel"]["mobile"].stringValue
let home = user["tel"]["home"].stringValue
 
print("User: uid:\(uid!),uname:\(uname!),mobile:\(mobile!),home:\(home!)")

相关文章

网友评论

      本文标题:Swift - 解析XML格式数据(分别使用KissXML)

      本文链接:https://www.haomeiwen.com/subject/xwmcqktx.html