Skip to content

Commit

Permalink
Merge pull request #27 from yahoojapan/feature/parse_invalid_character
Browse files Browse the repository at this point in the history
catching invalid character error
  • Loading branch information
kazuhiro4949 authored Nov 16, 2018
2 parents 7e930e7 + 73fb8e2 commit 7a8a7fb
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 11 deletions.
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ let str = """
</ResultSet>
"""

xml = try! XML.parse(string) // -> XML.Accessor
xml = try! XML.parse(str) // -> XML.Accessor
```
+ from NSData
```swift
Expand All @@ -136,11 +136,27 @@ let str = """
</ResultSet>
"""

let data = string.dataUsingEncoding(NSUTF8StringEncoding)
let data = str.data(using: .utf8)

xml = XML.parse(data) // -> XML.Accessor
```

+ with invalid character

```swift
let srt = "<xmlopening>@ß123\u{1c}</xmlopening>"

let xml = XML.parse(str.data(using: .utf8))

if case .failure(XMLError.intrupptedParseError) = xml {
print("invalid character")
}

```

For more, see https://developer.apple.com/documentation/foundation/xmlparser/errorcode


### 2. Access child Elements
```swift
let element = xml.ResultSet // -> XML.Accessor
Expand Down
3 changes: 2 additions & 1 deletion SwiftyXMLParser/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import Foundation

public enum XMLError: Error {
case parseError
case failToEncodeString
case intrupptedParseError(rawError: Error)
case accessError(description: String)
}
15 changes: 14 additions & 1 deletion SwiftyXMLParser/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,22 @@ import Foundation

extension XML {
class Parser: NSObject, XMLParserDelegate {
/// If it has value, Parser is interuppted by error. (e.g. using invalid character)
/// So the result of parsing is missing.
/// See https://developer.apple.com/documentation/foundation/xmlparser/errorcode
private(set) var error: XMLError?

func parse(_ data: Data) -> Accessor {
stack = [Element]()
stack.append(documentRoot)
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
return Accessor(documentRoot)
if let error = error {
return Accessor(error)
} else {
return Accessor(documentRoot)
}
}

override init() {
Expand Down Expand Up @@ -75,5 +84,9 @@ extension XML {
}
stack.removeLast()
}

func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
error = .intrupptedParseError(rawError: parseError)
}
}
}
4 changes: 2 additions & 2 deletions SwiftyXMLParser/XML.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ open class XML {
*/
open class func parse(_ str: String) throws -> Accessor {
guard let data = str.data(using: String.Encoding.utf8) else {
throw XMLError.parseError
throw XMLError.failToEncodeString
}

return Parser().parse(data)
Expand All @@ -130,7 +130,7 @@ open class XML {
*/
open class func parse(_ str: String, trimming manner: CharacterSet) throws -> Accessor {
guard let data = str.data(using: String.Encoding.utf8) else {
throw XMLError.parseError
throw XMLError.failToEncodeString
}

return Parser(trimming: manner).parse(data)
Expand Down
25 changes: 21 additions & 4 deletions SwiftyXMLParserTests/ParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ class ParserTests: XCTestCase {
}

let xml = XML.Parser().parse(data)
if let _ = xml["ResultSet"].error {
XCTFail("fail to parse")
if case .failure(XMLError.intrupptedParseError) = xml {
XCTAssert(true, "Parsed Failure because of the invalid character")
} else {
XCTAssert(true, "success to parse")
XCTAssert(false, "fail")
}
}

Expand Down Expand Up @@ -142,5 +142,22 @@ class ParserTests: XCTestCase {
} else {
XCTAssert(false, "fail")
}
}
}

func testParseErrorToInvalidCharacter() {
let str = "<xmlopening>@ß123\u{1c}</xmlopening>"
let xml = XML.Parser().parse(str.data(using: .utf8)!)

if case .failure(XMLError.intrupptedParseError) = xml {
XCTAssert(true, "Parsed Failure because of the invalid character")
} else {
XCTAssert(false, "fail")
}
}

func testNotParseErrorToInvalidCharacter() {
let str = "<xmlopening>@ß123\u{1c}</xmlopening>".addingPercentEncoding(withAllowedCharacters: CharacterSet.controlCharacters.inverted)!
let xml = XML.Parser().parse(str.data(using: .utf8)!)
XCTAssertEqual("@ß123\u{1c}", xml["xmlopening"].text?.removingPercentEncoding, "Parsed Success and trim them")
}
}
2 changes: 1 addition & 1 deletion SwiftyXMLParserTests/XMLTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class XMLTests: XCTestCase {


func testSuccessParseFromDoublebyteSpace() {
guard let xml = try? XML.parse("<Name> <Name>") else {
guard let xml = try? XML.parse("<Name> </Name>") else {
XCTFail("Fail Prase")
return
}
Expand Down

0 comments on commit 7a8a7fb

Please sign in to comment.