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.
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.
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).