1. //
  2. // main.swift
  3. // C150805_libxml2r2
  4. // http://git.oschina.net/yao_yu/Swift2015/tree/master/C150805_libxml2r2?dir=1&filepath=C150805_libxml2r2&oid=f80a7498226526b991e7913298c15cd38480aea5&sha=c073af33d0534a10098bb8fcc0706c2fd489dc3f
  5. //
  6. // Created by yao_yu on 15/8/5.
  7. // Copyright © 2015年 yao_yu. All rights reserved.
  8. //
  9.  
  10. import Foundation
  11.  
  12. /* ---------- 扩展 ---------- */
  13.  
  14. extension NSString{
  15. convenience init?(urlString:String, encoding:NSStringEncoding) {
  16. let url = NSURL(string: urlString)
  17. do {
  18. try self.init(contentsOfURL: url!, encoding: encoding)
  19. } catch {}
  20. }
  21. }
  22.  
  23. extension String {
  24. init?(XMLChar char: UnsafePointer<xmlChar>){
  25. self.init()
  26. if char != nil {
  27. self = String.fromCString(UnsafePointer<CChar>(char))!
  28. }
  29. }
  30. }
  31.  
  32. /* ---------- XML节点 ---------- */
  33.  
  34. class XMLNode {
  35. var xmlDoc:xmlDocPtr = nil
  36. var xmlNode:xmlNodePtr = nil
  37.  
  38. init(node:xmlNodePtr, document:xmlDocPtr) {
  39. self.xmlNode = node
  40. self.xmlDoc = document
  41. }
  42.  
  43. convenience init(document:xmlDocPtr) {
  44. self.init(node:xmlDocGetRootElement(document), document:document)
  45. }
  46.  
  47. lazy var rawContent:String? = {
  48. return XMLNodeGetContent(self.xmlNode)
  49. // return XMLNodeGetString(self.xmlDoc, xmlNode: self.xmlNode)
  50. }()
  51.  
  52. lazy var children:[XMLNode] = {
  53. return self.xmlNodes2XMLNodes(XMLNodeGetChildren(self.xmlNode))
  54. }()
  55.  
  56. lazy var attributes: [String: String] = {
  57. return XMLNodeGetAttributes(self.xmlNode)
  58. }()
  59.  
  60. subscript(key:String) -> String? {
  61. return attributes[key]
  62. }
  63.  
  64. private func xmlNodes2XMLNodes(nodes:[xmlNodePtr]) -> [XMLNode] {
  65. var xmlNodes = [XMLNode]()
  66. for node in nodes{
  67. xmlNodes.append(XMLNode(node: node, document: xmlDoc))
  68. }
  69. return xmlNodes
  70.  
  71. //下面的代码引发:Command failed due to signal: Abort trap: 6
  72. //return nodes.map{[unowned self] in XMLNode(node:$0, document:self.xmlDoc)}
  73. }
  74. }
  75.  
  76. extension XMLNode {
  77. func xPath(xpath: String) -> [XMLNode] {
  78. return xmlNodes2XMLNodes(XMLFindXPath(self.xmlDoc, xPath: xpath))
  79. }
  80. }
  81.  
  82. /* ---------- libxml2读取工具函数 ---------- */
  83.  
  84. func XMLNodeGetString(doc:xmlDocPtr, xmlNode:xmlNodePtr) -> String? {
  85. let contentChars = xmlNodeListGetString(doc, xmlNode, )
  86. if contentChars == nil { return nil }
  87. let contentString = String(XMLChar: contentChars)
  88. free(contentChars)
  89. assert(contentString != nil, "XMLNodeGetString: 值转换不成功")
  90. return contentString
  91. }
  92.  
  93. func XMLNodeGetContent(xmlNode:xmlNodePtr) -> String? {
  94. let contentChars = xmlNodeGetContent(xmlNode)
  95. if contentChars == nil { return nil }
  96. let contentString = String(XMLChar: contentChars)
  97. free(contentChars)
  98. assert(contentString != nil, "XMLNodeGetContent: 值转换不成功")
  99. return contentString
  100. }
  101.  
  102. func XMLNodeGetChildren(xmlNode: xmlNodePtr) -> [xmlNodePtr] {
  103. var children = [xmlNodePtr]()
  104.  
  105. for var childNodePointer = xmlNode.memory.children;
  106. childNodePointer != nil;
  107. childNodePointer = childNodePointer.memory.next
  108. {
  109. if xmlNodeIsText(childNodePointer) == {
  110. children.append(childNodePointer)
  111. }
  112. }
  113.  
  114. return children
  115. }
  116.  
  117. func XMLNodeGetAttributes(xmlNode: xmlNodePtr) -> [String: String] {
  118. var result:[String: String] = [String: String]()
  119. for var attribute: xmlAttrPtr = xmlNode.memory.properties;
  120. attribute != nil;
  121. attribute = attribute.memory.next
  122. {
  123. if let key:String = String(XMLChar: attribute.memory.name) {
  124. if let value:String = XMLNodeGetContent(attribute.memory.children) {
  125. result[key] = value
  126. } else {
  127. result[key] = ""
  128. }
  129. } else {
  130. print((">>>>>>>>>>>>>>>>>>>>>>>>错误:", String(XMLChar: attribute.memory.name)))
  131. }
  132. }
  133. return result
  134. }
  135.  
  136. func XMLNodeGetAttribute(xmlNode: xmlNodePtr, key: String) -> String? {
  137. for var attribute: xmlAttrPtr = xmlNode.memory.properties;
  138. attribute != nil;
  139. attribute = attribute.memory.next
  140. {
  141. if key == String(XMLChar: attribute.memory.name) {
  142. return XMLNodeGetContent(attribute.memory.children)
  143. }
  144. }
  145. return nil
  146. }
  147.  
  148. func XMLFindXPath(xmlDoc:xmlDocPtr, xPath: String) -> [xmlNodePtr] {
  149. let xPathContext = xmlXPathNewContext(xmlDoc)
  150. if xPathContext == nil {
  151. return []
  152. }
  153.  
  154. xPathContext.memory.node = nil
  155.  
  156. let xPathObject = xmlXPathEvalExpression(UnsafePointer<xmlChar>(xPath.cStringUsingEncoding(NSUTF8StringEncoding)!), xPathContext)
  157. xmlXPathFreeContext(xPathContext)
  158. if xPathObject == nil {
  159. return []
  160. }
  161.  
  162. let nodeSet = xPathObject.memory.nodesetval
  163. if nodeSet == nil || nodeSet.memory.nodeNr == || nodeSet.memory.nodeTab == nil {
  164. xmlXPathFreeObject(xPathObject)
  165. return []
  166. }
  167.  
  168. var resultNodes = [xmlNodePtr]()
  169. for i in ..< Int(nodeSet.memory.nodeNr) {
  170. resultNodes.append(nodeSet.memory.nodeTab[i])
  171. }
  172.  
  173. xmlXPathFreeObject(xPathObject)
  174.  
  175. return resultNodes
  176. }
  177.  
  178. func XMLReadNSData(data:NSData?, encoding:NSStringEncoding = NSUTF8StringEncoding, isXML:Bool = false) -> xmlDocPtr? {
  179. if let data = data {
  180. let cBuffer = UnsafePointer<CChar>(data.bytes)
  181. let cSize = CInt(data.length)
  182. //
  183. // let cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding)
  184. // let cfEncodingAsString:CFStringRef = CFStringConvertEncodingToIANACharSetName(cfEncoding)
  185. // let cEncoding:UnsafePointer<CChar> = CFStringGetCStringPtr(cfEncodingAsString, CFStringEncoding(0))
  186.  
  187. if isXML {
  188. let options = CInt(XML_PARSE_RECOVER.rawValue)
  189. return xmlReadMemory(cBuffer, cSize, nil, nil, options)
  190. } else {
  191. let options = CInt(HTML_PARSE_RECOVER.rawValue | HTML_PARSE_NOWARNING.rawValue | HTML_PARSE_NOERROR.rawValue)
  192. return htmlReadMemory(cBuffer, cSize, nil, nil, options)
  193. }
  194. }
  195. return nil
  196. }
  197.  
  198. let GB18030_2000_Encoding = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringEncodings.GB_18030_2000.rawValue))
  199.  
  200. /* ---------- 测试代码 ---------- */
  201.  
  202. class CElapseTime {
  203. var startTime:NSDate
  204. var prompt:String
  205. var unsed:Bool = false
  206.  
  207. init(prompt:String) {
  208. self.startTime = NSDate()
  209. self.prompt = prompt
  210. }
  211.  
  212. var newprompt:String {
  213. return "\(prompt)耗时:\(NSDate().timeIntervalSinceDate(startTime))"
  214. }
  215. }
  216.  
  217. func testParseSina() {
  218.  
  219. var sURL:String
  220. var encoding:UInt
  221.  
  222. (sURL,encoding) = ("http://www.baidu.com", NSUTF8StringEncoding)
  223. print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\(sURL)")
  224.  
  225. var timer = CElapseTime(prompt: "读取网页")
  226. //let sContent = NSString(urlString:sURL, encoding: encoding)
  227. var sContent:NSString? = nil
  228. do{
  229. try sContent = NSString(contentsOfFile: "/Volumes/Data/Document/Test/sample.txt", encoding: NSUTF8StringEncoding)
  230. } catch {
  231.  
  232. }
  233. print(timer.newprompt)
  234. let sTimer1 = timer.newprompt
  235. timer = CElapseTime(prompt: "数据解析")
  236.  
  237. if let doc = XMLReadNSData(sContent?.dataUsingEncoding(NSUTF8StringEncoding)){
  238. let rootNode = XMLNode(document: doc)
  239. let findNodes = rootNode.xPath("//div")
  240. for childNode in findNodes {
  241. autoreleasepool{
  242. let _ = (childNode.attributes, childNode.rawContent)
  243. }
  244. // if let content = childNode.rawContent {
  245. // print(content)
  246. // }
  247. }
  248. print(findNodes.count)
  249. }
  250. print(sTimer1)
  251. print(timer.newprompt)
  252. }
  253.  
  254. testParseSina()

在Swift中使用libxml2的更多相关文章

  1. swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明

    关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...

  2. 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON

    项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...

  3. Swift中的可选链与内存管理(干货系列)

    干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...

  4. 在Swift中实现单例方法

    在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...

  5. [翻译]理解Swift中的Optional

    原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...

  6. 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型

    有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...

  7. swift 中指针的使用UnsafeMutablePointer

    在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...

  8. swift 中数据类型那个的转换

    在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,

  9. swift中Range的使用书名

    在swift中Range有两种用法 1.把字符串转换成NSString来使用 //这里是把swift的字符换转换成了nsstring 使用 let str :NSString = text.strin ...

随机推荐

  1. 网上下载的 java开源项目 如何 打jar包

    目前很多java开源项目(例如qlexpress)只提供了源码,没有提供jar,下面提供maven打jar包的方法. 1.进入qlexpress下载后源代码所在的目录,此目录应包含pom.xml,如下 ...

  2. iOS开发 Xcode中的Info.plist字段含义

    Info.plist用于向iOS提供关于app,bundle或者framework的一些重要信息.它指定了比如一个应用应该怎样启动,它如何被本地化,应用的名称,要显示的图标,还有更多.Info.pli ...

  3. java接口相关例题

    java接口相关习题 interface Graphics{  //接口里面只能用抽象方法  public abstract double area();    }//设置 平面类class Plan ...

  4. 编译C++,找不到头文件(fatal error: string: No such file or directory)

    在androidproject中编译C++时,找不到头文件,报错例如以下: fatal error: string: No such file or directory 解决该问题须要在Android ...

  5. 使用solrj操作solr索引库,solr是lucene服务器

    客户端开发 Solrj 客户端开发 Solrj Solr是搭建好的lucene服务器 当然不可能完全满足一般的业务需求 可能 要针对各种的架构和业务调整 这里就需要用到Solrj了 Solrj是Sol ...

  6. How and Why Unsafe is Used in Java---reference

    By Peter Lawrey https://www.voxxed.com/blog/2014/12/how-and-why-unsafe-is-used-in-java/ Overview sun ...

  7. Using JAAS Authentication in Java Clients---weblogic document

    The following topics are covered in this section: JAAS and WebLogic Server JAAS Authentication Devel ...

  8. TableView的优化

    一:什么是TableView的优化以及为什么要优化 1)CPU(中央处理器)和GPU(图形处理器):CPU主要从事逻辑计算的一些工作:GPU主要从事图形处理方面的工作. 2)CPU和GPU的共同点: ...

  9. 从源码角度理解android动画Interpolator类的使用

    做过android动画的人对Interpolator应该不会陌生,这个类主要是用来控制android动画的执行速率,一般情况下,如果我们不设置,动画都不是匀速执行的,系统默认是先加速后减速这样一种动画 ...

  10. 如何让MFC程序关闭按钮失效,也无法右击任务栏关闭窗口来关闭?

    如何让MFC程序关闭按钮失效,也无法右击任务栏关闭窗口来关闭,即右键任务栏的关闭窗口失效呢?很简单,有一个小窍门就是:响应IDCANCEL消息,具体实现如下: 首先定义消息映射:ON_BN_CLICK ...