[Swift通天遁地]七、数据与安全-(2)对XML和HTML文档的快速解析

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10300747.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

目录:[Swift]通天遁地Swift

本文将演示使用Fuzi(斧子)类库实现对XML和HTML文档的快速解析。

首先确保在项目中已经安装了所需的第三方库。

点击【Podfile】,查看安装配置文件。

1 platform :ios, '12.0'
2 use_frameworks!
3 
4 target 'DemoApp' do
5     source 'https://github.com/CocoaPods/Specs.git'
6     pod 'Fuzi'
7 end

根据配置文件中的相关配置,安装第三方库。

然后点击打开【DemoApp.xcworkspace】项目文件。

在项目导航区,打开视图控制器的代码文件【ViewController.swift】

  1 import UIKit
  2 //引入已经安装的第三方类库
  3 import Fuzi
  4 
  5 class ViewController: UIViewController {
  6     
  7     override func viewDidLoad() {
  8         super.viewDidLoad()
  9         // Do any additional setup after loading the view, typically from a nib.
 10         //实现对XML文档的解析
 11         parseXML()
 12         //实现对HTML文档的解析
 13         parseHTML()
 14     }
 15     
 16     //添加一个方法,实现对XML文档的解析
 17     func parseXML()
 18     {
 19         //从项目中读取指定文件名称的待解析的文档。
 20         let fileUrl = URL(fileURLWithPath: ((#file as NSString).deletingLastPathComponent as NSString).appendingPathComponent("nutrition.xml"))
 21         //添加一个异常捕捉语句,用来处理对XML文档的解析操作。
 22         do
 23         {
 24             //读取待解析的文档,并存储在一个数据常量中。
 25             let data = try Data(contentsOf: fileUrl)
 26             //将加载的数据转换成文档对象。
 27             let document = try XMLDocument(data: data)
 28             
 29             //获得文档对象的根节点,并在控制台输出根节点的标签的值。
 30             if let root = document.root
 31             {
 32                 //输出日志信息
 33                 print("Root Element: (String(describing: root.tag))")
 34                 
 35                 print("
Daily values:")
 36                 //获得根节点中指定标签的节点,
 37                 //然后获得该节点下的所有子节点,
 38                 //并对子节点进行遍历。
 39                 for element in root.firstChild(tag: "daily-values")?.children ?? []
 40                 {
 41                     //获得节点标签的名称
 42                     let nutrient = element.tag
 43                     //获得节点的值
 44                     let amount = element.numberValue
 45                     //获得节点属性的值
 46                     let unit = element["units"]
 47                     //在控制台输出节点各元素的值
 48                     print("- (amount!)(unit!) (nutrient!)")
 49                 }
 50                 //输出一个换行符
 51                 print("
")
 52                 
 53                 //通过X路径格式,获得指定的节点。
 54                 //这里获得食物节点下的名称子节点。
 55                 var xpath = "//food/name"
 56                 //在控制台输出该节点。
 57                 print("XPath Search: (xpath)")
 58                 
 59                 //遍历所有的名称节点
 60                 for element in document.xpath(xpath)
 61                 {
 62                     //并在控制台输出食物的名称
 63                     print("(element)")
 64                 }
 65                 //输出另一个换行符
 66                 print("
")
 67                 
 68                 //还可以通过和CSS相似的方法,来查找指定的节点。
 69                 //这里获得食物节点下的指定的子节点。
 70                 let css = "food > serving[units]"
 71                 //初始化一个文档元素
 72                 var blockElement:XMLElement? = nil
 73                 //在控制台输出搜索路径
 74                 print("CSS Search: (css)")
 75                 
 76                 //对指定路径下的节点进行遍历
 77                 for (index, element) in document.css(css).enumerated()
 78                 {
 79                     //当循环的索引为数字1时,                    
 80                     if index == 1
 81                     {
 82                         //获得遍历的节点。
 83                         blockElement = element
 84                         break
 85                     }
 86                 }
 87                 //然后在控制台输出第二个节点。
 88                 print("Second element: (blockElement!)
")
 89                 
 90                 //在控制台输出食物节点下的,名称子节点的X路径。
 91                 xpath = "//food/name"
 92                 print("XPath Search: (xpath)")
 93                 
 94                 //获得文档中的指定路径的第一个节点,
 95                 //在控制台输出该节点的内容。
 96                 let firstElement = document.firstChild(xpath: xpath)!
 97                 print("First element: (firstElement)")
 98             }
 99         }
100         catch
101         {
102             print("Something went wrong :(")
103         }
104     }
105     
106     //添加一个方法,实现对HTML文档的解析
107     func parseHTML()
108     {
109         //从项目中读取指定的网页文件
110         let fileUrl = URL(fileURLWithPath: ((#file as NSString).deletingLastPathComponent as NSString).appendingPathComponent("index.html"))
111         //添加一个异常捕捉语句,用来处理对HTML文档的解析操作。
112         do
113         {
114             //获得指定位置的网页文件,将文件存储在数据对象中。
115             let data = try Data(contentsOf: fileUrl)
116             //将网页数据转换成文档对象。
117             let doc = try HTMLDocument(data: data)
118             
119             //获得文档对象中的第一个指定的节点,            
120             if let elementById = doc.firstChild(css: "#copyright")
121             {
122                 //并在控制台输出该节点的内容。
123                 print(elementById.stringValue)
124             }
125             
126             //获得文档对象中的所有链接节点,
127             //并对链接节点进行遍历
128             for link in doc.css("a, link")
129             {
130                 //在控制台输出链接的路径
131                 print(link.rawXML)
132                 print(link["href"] as Any)
133             }
134             
135             //获得主体节点下的所有链接节点,
136             if let firstAnchor = doc.firstChild(xpath: "//body/a")
137             {
138                 //并输出第一个网络链接。
139                 print(firstAnchor["href"] as Any)
140             }
141             
142             //获得头结点下的所有脚本节点,
143             for script in doc.xpath("//head/script")
144             {
145                 //并输出脚本节点的文档路径
146                 print(script["src"] ?? "")
147             }
148             
149             //获得主体节点下的所有链接节点,
150             if let result = doc.eval(xpath: "count(//body/a)")
151             {
152                 //并在控制台输出该数量
153                 print("anchor count : (result.doubleValue)")
154             }
155             
156             //输出标题
157             print(doc.title as Any)
158             //输出头节点
159             print(doc.head as Any)
160             //输出主题节点
161             print(doc.body as Any)
162         }
163         catch
164         {
165             print("Something went wrong :(")
166         }
167     }
168     
169     override func didReceiveMemoryWarning() {
170         super.didReceiveMemoryWarning()
171         // Dispose of any resources that can be recreated.
172     }
173 }
原文地址:https://www.cnblogs.com/strengthen/p/10300747.html