XMLReader.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // XMLReader.swift
  3. // Samples
  4. //
  5. // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. import Foundation
  13. let kXMLReaderTextNodeKey = "text"
  14. let kXMLReaderAttributePrefix = "@"
  15. struct XMLReaderOptions: OptionSet {
  16. let rawValue: Int
  17. static let processNamespaces = XMLReaderOptions(rawValue: 1 << 0)
  18. static let reportNamespacePrefixes = XMLReaderOptions(rawValue: 1 << 1)
  19. static let resolveExternalEntities = XMLReaderOptions(rawValue: 1 << 2)
  20. }
  21. class XMLReader: NSObject, XMLParserDelegate {
  22. private var dictionaryStack: [NSMutableDictionary] = []
  23. private var textInProgress: NSMutableString = NSMutableString()
  24. private var errorPointer: NSError?
  25. class func dictionary(forXMLData data: Data, error: NSError) -> NSDictionary? {
  26. let reader = XMLReader()
  27. let rootDictionary = reader.object(withData: data, options: [])
  28. return rootDictionary
  29. }
  30. class func dictionary(forXMLString string: String, error: NSError) -> NSDictionary? {
  31. let data = string.data(using: .utf8)
  32. return XMLReader.dictionary(forXMLData: data!, error: error)
  33. }
  34. class func dictionary(forXMLData data: Data, options: XMLReaderOptions, error: NSError) -> NSDictionary? {
  35. let reader = XMLReader()
  36. let rootDictionary = reader.object(withData: data, options: options)
  37. return rootDictionary
  38. }
  39. class func dictionary(forXMLString string: String, options: XMLReaderOptions, error: NSError) -> NSDictionary? {
  40. let data = string.data(using: .utf8)
  41. return XMLReader.dictionary(forXMLData: data!, options: options, error: error)
  42. }
  43. func object(withData data: Data, options: XMLReaderOptions) -> NSDictionary? {
  44. self.dictionaryStack = [NSMutableDictionary]()
  45. self.textInProgress = NSMutableString()
  46. self.dictionaryStack.append(NSMutableDictionary())
  47. let parser = XMLParser(data: data)
  48. parser.delegate = self
  49. let success = parser.parse()
  50. if success {
  51. let resultDict = self.dictionaryStack[0]
  52. return resultDict
  53. }
  54. return nil
  55. }
  56. func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
  57. let parentDict = self.dictionaryStack.last
  58. var childDict = NSMutableDictionary()
  59. childDict.addEntries(from: attributeDict)
  60. if let existingValue = parentDict?[elementName] {
  61. var array: NSMutableArray? = nil
  62. if let existingArray = existingValue as? NSMutableArray {
  63. array = existingArray
  64. } else {
  65. array = NSMutableArray()
  66. array?.add(existingValue)
  67. parentDict?[elementName] = array
  68. }
  69. array?.add(childDict)
  70. } else {
  71. parentDict?[elementName] = childDict
  72. }
  73. self.dictionaryStack.append(childDict)
  74. }
  75. func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
  76. let dictInProgress = self.dictionaryStack.last
  77. if self.textInProgress.length > 0 {
  78. let trimmedString = self.textInProgress.trimmingCharacters(in: .whitespacesAndNewlines)
  79. dictInProgress?[kXMLReaderTextNodeKey] = trimmedString
  80. self.textInProgress = NSMutableString()
  81. }
  82. self.dictionaryStack.removeLast()
  83. }
  84. func parser(_ parser: XMLParser, foundCharacters string: String) {
  85. self.textInProgress.append(string)
  86. }
  87. func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
  88. self.errorPointer = parseError as NSError
  89. }
  90. }