diff --git a/Sources/XMLCoder/Auxiliaries/XMLStackParser.swift b/Sources/XMLCoder/Auxiliaries/XMLStackParser.swift
index 066b68f4..499f4450 100644
--- a/Sources/XMLCoder/Auxiliaries/XMLStackParser.swift
+++ b/Sources/XMLCoder/Auxiliaries/XMLStackParser.swift
@@ -12,18 +12,29 @@ class XMLStackParser: NSObject {
var root: XMLCoderElement?
private var stack: [XMLCoderElement] = []
- static func parse(with data: Data,
- errorContextLength length: UInt) throws -> KeyedBox {
+ static func parse(
+ with data: Data,
+ errorContextLength length: UInt,
+ shouldProcessNamespaces: Bool
+ ) throws -> KeyedBox {
let parser = XMLStackParser()
- let node = try parser.parse(with: data, errorContextLength: length)
+ let node = try parser.parse(
+ with: data,
+ errorContextLength: length,
+ shouldProcessNamespaces: shouldProcessNamespaces
+ )
return node.flatten()
}
- func parse(with data: Data,
- errorContextLength: UInt) throws -> XMLCoderElement {
+ func parse(
+ with data: Data,
+ errorContextLength: UInt,
+ shouldProcessNamespaces: Bool
+ ) throws -> XMLCoderElement {
let xmlParser = XMLParser(data: data)
+ xmlParser.shouldProcessNamespaces = shouldProcessNamespaces
xmlParser.delegate = self
guard !xmlParser.parse(), root == nil else {
@@ -92,8 +103,8 @@ extension XMLStackParser: XMLParserDelegate {
func parser(_: XMLParser,
didStartElement elementName: String,
- namespaceURI _: String?,
- qualifiedName _: String?,
+ namespaceURI: String?,
+ qualifiedName: String?,
attributes attributeDict: [String: String] = [:]) {
let element = XMLCoderElement(key: elementName, attributes: attributeDict)
stack.append(element)
diff --git a/Sources/XMLCoder/Decoder/XMLDecoder.swift b/Sources/XMLCoder/Decoder/XMLDecoder.swift
index 6b941f69..653c6c54 100644
--- a/Sources/XMLCoder/Decoder/XMLDecoder.swift
+++ b/Sources/XMLCoder/Decoder/XMLDecoder.swift
@@ -245,6 +245,11 @@ open class XMLDecoder {
/// span more than a few lines.
open var errorContextLength: UInt = 0
+ /** A boolean value that determines whether the parser reports the
+ namespaces and qualified names of elements. The default value is `false`.
+ */
+ open var shouldProcessNamespaces: Bool = false
+
/// Options set on the top-level encoder to pass down the decoding hierarchy.
struct Options {
let dateDecodingStrategy: DateDecodingStrategy
@@ -283,7 +288,8 @@ open class XMLDecoder {
) throws -> T {
let topLevel: Box = try XMLStackParser.parse(
with: data,
- errorContextLength: errorContextLength
+ errorContextLength: errorContextLength,
+ shouldProcessNamespaces: shouldProcessNamespaces
)
let decoder = XMLDecoderImplementation(referencing: topLevel, options: options)
diff --git a/Tests/XMLCoderTests/Auxiliary/XMLStackParserTests.swift b/Tests/XMLCoderTests/Auxiliary/XMLStackParserTests.swift
index 958f3d1e..b02d4791 100644
--- a/Tests/XMLCoderTests/Auxiliary/XMLStackParserTests.swift
+++ b/Tests/XMLCoderTests/Auxiliary/XMLStackParserTests.swift
@@ -21,8 +21,11 @@ class XMLStackParserTests: XCTestCase {
"""
let xmlData = xmlString.data(using: .utf8)!
- let root: XMLCoderElement? = try parser.parse(with: xmlData,
- errorContextLength: 0)
+ let root: XMLCoderElement? = try parser.parse(
+ with: xmlData,
+ errorContextLength: 0,
+ shouldProcessNamespaces: false
+ )
let expected = XMLCoderElement(
key: "container",
@@ -46,7 +49,10 @@ class XMLStackParserTests: XCTestCase {
let xmlString = "lorem ipsum"
let xmlData = xmlString.data(using: .utf8)!
- XCTAssertThrowsError(try parser.parse(with: xmlData,
- errorContextLength: 0))
+ XCTAssertThrowsError(try parser.parse(
+ with: xmlData,
+ errorContextLength: 0,
+ shouldProcessNamespaces: false
+ ))
}
}
diff --git a/Tests/XMLCoderTests/NamespaceTest.swift b/Tests/XMLCoderTests/NamespaceTest.swift
new file mode 100644
index 00000000..f0360e9d
--- /dev/null
+++ b/Tests/XMLCoderTests/NamespaceTest.swift
@@ -0,0 +1,38 @@
+//
+// NamespaceTest.swift
+// XMLCoder
+//
+// Created by Max Desiatov on 27/02/2019.
+//
+
+import Foundation
+import XCTest
+@testable import XMLCoder
+
+private let xmlData = """
+
+
+ Apples
+ Bananas
+
+
+""".data(using: .utf8)!
+
+private struct Table: Codable, Equatable {
+ struct TR: Codable, Equatable {
+ let td: [String]
+ }
+
+ let tr: TR
+}
+
+class NameSpaceTest: XCTestCase {
+ func testDecoder() throws {
+ let decoder = XMLDecoder()
+ decoder.shouldProcessNamespaces = true
+
+ let decoded = try decoder.decode(Table.self, from: xmlData)
+
+ XCTAssertEqual(decoded, Table(tr: .init(td: ["Apples", "Bananas"])))
+ }
+}
diff --git a/XMLCoder.xcodeproj/project.pbxproj b/XMLCoder.xcodeproj/project.pbxproj
index 33627d76..4a8f642d 100644
--- a/XMLCoder.xcodeproj/project.pbxproj
+++ b/XMLCoder.xcodeproj/project.pbxproj
@@ -86,6 +86,7 @@
D14D8A8621F1D6B300B0D31A /* SingleChildTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D14D8A8521F1D6B300B0D31A /* SingleChildTests.swift */; };
D162674321F9B2AF0056D1D8 /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D162674121F9B2850056D1D8 /* OptionalTests.swift */; };
D1CB1EF521EA9599009CAF02 /* RJITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_37 /* RJITest.swift */; };
+ D1CFC8242226B13F00B03222 /* NamespaceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CFC8222226AFB400B03222 /* NamespaceTest.swift */; };
D1E0C85321D8E65E0042A261 /* ErrorContextTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1E0C85121D8E6540042A261 /* ErrorContextTest.swift */; };
D1E0C85521D91EBF0042A261 /* Metatypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1E0C85421D91EBF0042A261 /* Metatypes.swift */; };
D1FC040521C7EF8200065B43 /* RJISample.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1FC040421C7EF8200065B43 /* RJISample.swift */; };
@@ -198,6 +199,7 @@
D11979B721F5EA5400A9C574 /* XMLCoder.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = XMLCoder.podspec; sourceTree = ""; };
D14D8A8521F1D6B300B0D31A /* SingleChildTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleChildTests.swift; sourceTree = ""; };
D162674121F9B2850056D1D8 /* OptionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalTests.swift; sourceTree = ""; };
+ D1CFC8222226AFB400B03222 /* NamespaceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NamespaceTest.swift; sourceTree = ""; };
D1E0C85121D8E6540042A261 /* ErrorContextTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorContextTest.swift; sourceTree = ""; };
D1E0C85421D91EBF0042A261 /* Metatypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Metatypes.swift; sourceTree = ""; };
D1FC040421C7EF8200065B43 /* RJISample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RJISample.swift; sourceTree = ""; };
@@ -384,6 +386,7 @@
B3BE1D602202C1F600259831 /* DynamicNodeEncodingTest.swift */,
A61DCCD621DF8DB300C0A19D /* ClassTests.swift */,
D14D8A8521F1D6B300B0D31A /* SingleChildTests.swift */,
+ D1CFC8222226AFB400B03222 /* NamespaceTest.swift */,
);
name = XMLCoderTests;
path = Tests/XMLCoderTests;
@@ -625,6 +628,7 @@
D1FC040521C7EF8200065B43 /* RJISample.swift in Sources */,
BF63EF0A21CD7C1A001D38C5 /* URLTests.swift in Sources */,
BF9457CE21CBB516005ACFDE /* StringBoxTests.swift in Sources */,
+ D1CFC8242226B13F00B03222 /* NamespaceTest.swift in Sources */,
BF9457D021CBB516005ACFDE /* UIntBoxTests.swift in Sources */,
OBJ_80 /* BooksTest.swift in Sources */,
OBJ_81 /* BreakfastTest.swift in Sources */,