| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /**
- * https://github.com/tadija/AEXML
- * Copyright (c) Marko Tadić 2014-2019
- * Licensed under the MIT license. See LICENSE file.
- */
- import Foundation
- #if canImport(FoundationXML)
- import FoundationXML
- #endif
- /// Simple wrapper around `Foundation.XMLParser`.
- internal class Parser: NSObject, XMLParserDelegate {
-
- // MARK: - Properties
-
- let document: Document
- let data: Data
-
- var currentParent: Element?
- var currentElement: Element?
- var currentValue = String()
-
- var parseError: Error?
- private lazy var parserSettings: Options.ParserSettings = {
- return document.options.parserSettings
- }()
-
- // MARK: - Lifecycle
-
- init(document: Document, data: Data) {
- self.document = document
- self.data = data
- currentParent = document
-
- super.init()
- }
-
- // MARK: - API
-
- func parse() throws {
- let parser = Foundation.XMLParser(data: data)
- parser.delegate = self
- parser.shouldProcessNamespaces = parserSettings.shouldProcessNamespaces
- parser.shouldReportNamespacePrefixes = parserSettings.shouldReportNamespacePrefixes
- parser.shouldResolveExternalEntities = parserSettings.shouldResolveExternalEntities
-
- let success = parser.parse()
-
- if !success {
- guard let error = parseError else { throw XMLError.parsingFailed }
- throw error
- }
- }
-
- // MARK: - XMLParserDelegate
-
- func parser(_ parser: Foundation.XMLParser,
- didStartElement elementName: String,
- namespaceURI: String?,
- qualifiedName qName: String?,
- attributes attributeDict: [String : String]) {
- currentValue = String()
- currentElement = currentParent?.addChild(name: elementName, attributes: attributeDict)
- currentParent = currentElement
- }
-
- func parser(_ parser: Foundation.XMLParser, foundCharacters string: String) {
- currentValue.append(string)
- currentElement?.value = currentValue.isEmpty ? nil : currentValue
- }
-
- func parser(_ parser: Foundation.XMLParser,
- didEndElement elementName: String,
- namespaceURI: String?,
- qualifiedName qName: String?) {
- if parserSettings.shouldTrimWhitespace {
- currentElement?.value = currentElement?.value?
- .trimmingCharacters(in: .whitespacesAndNewlines)
- }
- currentParent = currentParent?.parent
- currentElement = nil
- }
-
- func parser(_ parser: Foundation.XMLParser, parseErrorOccurred parseError: Error) {
- self.parseError = parseError
- }
-
- }
|