XMLDocument and validate()

I have been trying to check issues in XML received from an external source and one thing which is stumping me is XMLDocument.validate(). The documentation indicates it should return true or false, but I always get a nil when a run it against XML, regardless of the validity state of the XML.

Sample XML (truncated but valid):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <book xmlns:ali="http://www.niso.org/schemas/ali/1.0/" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:oasis="http://www.niso.org/standards/z39-96/ns/oasis-exchange/table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:noNamespaceSchemaLocation="http://jats.nlm.nih.gov/extensions/bits/2.0/xsd/BITS-book-oasis2.xsd"> <book-body> <book-part> <body/> </book-part> </book-body> </book>

Swift Code (where dataString is a utf8 String of the XML document):

let dataXML = try! XMLDocument.init(xmlString: dataString, options: )
try? dataXML.validate()

I need to weed out the XML files which do not conform to the schema. What am I missing/doing wrong? Thanks in advance.

1 Like

/cc @Philippe_Hausler

Only in Obj-C. The documentation (validate() | Apple Developer Documentation) says:

In Swift, this method returns Void and is marked with the throws keyword to indicate that it throws an error in cases of failure.

And this code in a playground:

let dataXML = try! XMLDocument.init(xmlString: dataString, options: [])
do {
	try dataXML.validate()
}
catch {
	print (error)
}

prints:

Error Domain=NSXMLParserErrorDomain Code=1 "complex type 'annotation-xml.model': The content model is not determinist. local complex type: The content model is not determinist.

Thanks for the fast response. So it appears it is the schema involved which is the issue.

I'm getting a similar issue with validation. I've applied the do { try } catch { } change as noted, but I'm finding that no matter how I supply the schemaLocation, the schema resource cannot be located.

I've tried a local file (confirmed it exists and is accessible), a real file accessible via HTTP, and a non-existant file. The error message is always identical.

The error message also seems suspect, as the item it says it cannot locate is empty. Thoughts?

Error:

Validation failed with error: Error Domain=NSXMLParserErrorDomain Code=1 "Failed to locate the main schema resource at ''.
" UserInfo={NSLocalizedDescription=Failed to locate the main schema resource at ''.
}

Code:

func run() throws {
    // Validate the document
    var valid = false
    do {
        // Write out schema
        let schemaURL = URL(fileURLWithPath: "schema.xsd")
        try SVGXML.schema.write(to: schemaURL, atomically: true, encoding: .utf8)

        // Parse and validate document against schema
        let document = try XMLDocument(xmlString: documentString, options: .nodePreserveAll)
        let schemaNamespace = XMLNode.attribute(withName: "xmlns:xsi", stringValue: "http://www.w3.org/2001/XMLSchema") as! XMLNode
        let schemaLocationAttribute = XMLNode.attribute(withName: "xsi:schemaLocation", stringValue: "http://www.w3.org/2001/not_a_real_schema"/*schemaURL.absoluteString*/) as! XMLNode
        document.rootElement()?.addAttribute(schemaNamespace)
        document.rootElement()?.addAttribute(schemaLocationAttribute)
        try document.validate()
        valid = true
    } catch {
        print("Validation failed with error: \(error)")
    }

    // Emit validation result
    print(valid ? "1" : "0")
}

I’m hardly an XML guru but my understanding is that the xsi:schemaLocation attribute is meant to be a pair of values, separated by a space, where the first value is the namespace and the second value is the location. Your value only has a single attribute, so NSXMLDocument is passing the empty string down to libxml2 (which, btw, is where the Failed to locate the main schema resource at '' message is coming from).

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

You are absolutely correct! having 2 items separated by a space caused validation to continue. Unfortunate that the error message is so unhelpful...

Unfortunate that the error message is so unhelpful...

Quite. Feel free to file a bug about that.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple