SwiftyXMLParser 5.6.0

SwiftyXMLParser 5.6.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最新发布2021年11月
SPM支持 SPM

Kazuhiro Hayashi 维护。



  • 作者
  • kahayash

swiftyxmlparserlogo

Swift 5.0 Carthage compatible Version License Platform

使用 Swift 实现的简单 XML 解析器

这是什么?

这是一个受 SwiftyJSONSWXMLHash 启发的 XML 解析器。

Foundation 框架中的 NSXMLParser 是一种“SAX”解析器。它性能足够好,但使用上略有不便。因此,我们实现了一个将“DOM”解析器包装在它周围。

特性

  • 通过“索引”访问 XML 文档。
  • 将 XML 文档作为序列访问。
  • 易于调试 XML 路径。

要求

  • iOS 9.0+
  • tvOS 9.0+
  • macOS 10.10+
  • Swift 5.0

安装

Carthage

1. 创建 Cartfile

github "https://github.com/yahoojapan/SwiftyXMLParser"

2. 安装

> carthage update

CocoaPods

1. 创建 Podfile

platform :ios, '9.0'
use_frameworks!

pod "SwiftyXMLParser", :git => 'https://github.com/yahoojapan/SwiftyXMLParser.git'

2. 安装

> pod install

示例

import SwiftyXMLParser

let str = """
<ResultSet>
    <Result>
        <Hit index=\"1\">
            <Name>Item1</Name>
        </Hit>
        <Hit index=\"2\">
            <Name>Item2</Name>
        </Hit>
    </Result>
</ResultSet>
"""

// parse xml document
let xml = try! XML.parse(str)

// access xml element
let accessor = xml["ResultSet"]

// access XML Text

if let text = xml["ResultSet", "Result", "Hit", 0, "Name"].text {
    print(text)
}

if let text = xml.ResultSet.Result.Hit[0].Name.text {
    print(text)
}

// access XML Attribute
if let index = xml["ResultSet", "Result", "Hit", 0].attributes["index"] {
    print(index)
}

// enumerate child Elements in the parent Element
for hit in xml["ResultSet", "Result", "Hit"] {
    print(hit)
}

// check if the XML path is wrong
if case .failure(let error) =  xml["ResultSet", "Result", "TypoKey"] {
    print(error)
}

使用方法

1. 解析XML

  • 从字符串
let str = """
<ResultSet>
    <Result>
        <Hit index=\"1\">
            <Name>Item1</Name>
        </Hit>
        <Hit index=\"2\">
            <Name>Item2</Name>
        </Hit>
    </Result>
</ResultSet>
"""

xml = try! XML.parse(str) // -> XML.Accessor
  • 从NSData
let str = """
<ResultSet>
    <Result>
        <Hit index=\"1\">
            <Name>Item1</Name>
        </Hit>
        <Hit index=\"2\">
            <Name>Item2</Name>
        </Hit>
    </Result>
</ResultSet>
"""

let string = String(decoding: data, as: UTF8.self)

xml = XML.parse(data) // -> XML.Accessor
  • 包含无效字符
let srt = "<xmlopening>@ß123\u{1c}</xmlopening>"

let xml = XML.parse(str.data(using: .utf8))

if case .failure(XMLError.interruptedParseError) = xml {
  print("invalid character")
}

更多内容,请参阅 https://developer.apple.com/documentation/foundation/xmlparser/errorcode

2. 访问子元素

let element = xml.ResultSet // -> XML.Accessor

3. 访问孙元素

  • 使用字符串
let element = xml["ResultSet"]["Result"] // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>
  • 使用数组
let path = ["ResultSet", "Result"]
let element = xml[path] // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>
  • 使用可变参数
let element = xml["ResultSet", "Result"] // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>
  • 使用@dynamicMemberLookup
let element = xml.ResultSet.Result // -> <Result><Hit index=\"1\"><Name>Item1</Name></Hit><Hit index=\"2\"><Name>Item2</Name></Hit></Result>

4. 访问特定的孙元素

let element = xml.ResultSet.Result.Hit[1] // -> <Hit index=\"2\"><Name>Item2</Name></Hit>

5. 访问元素中的属性

if let attributeValue = xml.ResultSet.Result.Hit[1].attributes?["index"] {
  print(attributeValue) // -> 2
}

6. 在元素中访问文本

  • 带有可选绑定
if let text = xml.ResultSet.Result.Hit[1].Name.text {
    print(text) // -> Item2
} 
  • 带有自定义操作
struct Entity {
  var name = ""
}
let entity = Entity()
entity.name ?= xml.ResultSet.Result.Hit[1].Name.text // assign if it has text
  • 转换整型并赋值
struct Entity {
  var name: Int = 0
}
let entity = Entity()
entity.name ?= xml.ResultSet.Result.Hit[1].Name.int // assign if it has Int

还有其他语法糖,包括布尔型、URL和双精度型。

  • 将文本赋值给数组
struct Entity {
  var names = [String]()
}
let entity = Entity()
entity.names ?<< xml.ResultSet.Result.Hit[1].Name.text // assign if it has text

7. 访问CDATA

let str = """
<Data name="DATE">
    <value><![CDATA[2018-07-08]]></value>
</Data>
"""

// parse xml document
let xml = try! XML.parse(str)
        
if let cdata = xml.Data.value.element?.CDATA, 
   let cdataStr = String(data: cdata, encoding: .utf8) {
   print(cdataStr) // -> "2018-07-08"
}

7. 计算子元素数量

let numberOfHits = xml.ResultSet.Result.Hit.all?.count 

8. 检查错误

print(xml.ResultSet.Result.TypoKey) // -> "TypoKey not found."

9. 作为序列类型访问

  • for-in
for element in xml.ResultSet.Result.Hit {
  print(element.text)
}
  • map
xml.ResultSet.Result.Hit.map { $0.Name.text }

10. 生成XML文档

print(Converter(xml.ResultSet).makeDocument())

使用Alamofire

SwiftyXMLParser 与 Alamofire 配合良好。您可以轻松解析响应。

import Alamofire
import SwiftyXMLParser

Alamofire.request(.GET, "https://itunes.apple.com/us/rss/topgrossingapplications/limit=10/xml")
         .responseData { response in
            if let data = response.data {
                let xml = XML.parse(data)
                print(xml.feed.entry[0].title.text) // outputs the top title of iTunes app raning.
            }
        }

此外,还有 Alamofire 的扩展,可以与 SwiftyXMLParser 结合使用。

迁移指南

当前主分支 支持 Xcode10。如果您想使用与此库兼容的旧 swift 版本,请阅读 发布说明 并安装最后一个兼容版本。

许可协议

本软件遵循 MIT 许可协议发布,请参阅 LICENSE 文件。