2

I trying out with SWXMLHash and to mock a download from a website to parse, I created a file in the playground with the data. I got this as the response from URLSessionManager Data looks similar to:

3c3f786d 6c207665 7273696f 6e3d2731 ...

But of course much longer.

I read it in as follows:

guard let fileURL = Bundle.main.url(forResource: "xmlData", withExtension: "")
    else { fatalError("cannot load file")}
do {
    let xmlData = try Data(contentsOf: fileURL, options: .mappedIfSafe)
} catch {
    print(error)
}

This works I think, there is no error and if I print the data it returns 169735 bytes.

Then I try to parse it (inside the do block):

let xml = SWXMLHash.parse(xmlData)
print(xml)

This returns \n, so no output.

SWXMLHash provides a method that accepts a Data object. How can I get this to work?

koen
  • 5,383
  • 7
  • 50
  • 89
  • 1
    If you do `let xmlStr = String(data:xmlData, encoding:.utf8)`, it shows correctXML? According to this https://github.com/drmohundro/SWXMLHash/blob/master/Source/SWXMLHash.swift lines 92 & 106, even if it's a String, it convert it to Data first, so it should indeed work. – Larme Apr 25 '18 at 20:41
  • That returns the same as what is in the data file: `Optional("3c3f786d 6c207665 7273696f...`, so no xml file. Can I get more info out of `print(xmlData)`, instead of just the number of bytes? I'm wondering now what I have in the file is not a correct data representation of the xml. Will investigate. – koen Apr 25 '18 at 20:55
  • Quick way is doing `print(xmlData as NSData)`. Else, in your file, put the XMLString, not the hex representation one. Because you create a text with "Hex String", and not a "data binary file". There are way to revert it, but clearly, put the XML string directly in it. – Larme Apr 25 '18 at 20:58

1 Answers1

2

According to SWXMLHash

public func parse(_ xml: String) -> XMLIndexer {
    guard let data = xml.data(using: options.encoding) else {
        return .xmlError(.encoding)
    }
    return parse(data)
}

public func parse(_ data: Data) -> XMLIndexer {
    let parser: SimpleXmlParser = options.shouldProcessLazily
        ? LazyXMLParser(options)
        : FullXMLParser(options)
    return parser.parse(data)
}

Whereas you give a String or a Data object, internally it will parse a Data object doing a conversion if needed. It's a safe way of coding, this way all initialization methods pass through the same one, and fixing it fix all the different initialization.

So it should work.

Your issue is that you file is a string representation of HexData, not a RawHexData file.
The solution is to put in that file the XML String instead.

The Data(contentsOf: fileURL, options: .mappedIfSafe) will convert that XML String into a Hex representation of it. And then it will work.

Larme
  • 24,190
  • 6
  • 51
  • 81