I am trying to validate an XML Schema document against the schema for schemas (http://www.w3.org/2001/XMLSchema) using NSXMLDocument. I've gotten it to work correctly, and assumed that I was validating against a local schema.
However, I discovered that without a network connection, this validation doesn't work. Is there any way to force NSXMLDocument to use a local schema for validation?
The code I have working with a net connection:
xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:furl options:(NSXMLDocumentValidate | NSXMLNodePreserveAll)
error:&err];
NSXMLElement *rootElement = [xmlDoc rootElement];
NSMutableArray *namespaces = [[rootElement namespaces] mutableCopy];
[namespaces addObject:[NSXMLNode namespaceWithName:@"xsi" stringValue:@"http://www.w3.org/2001/XMLSchema-instance"]];
[rootElement setNamespaces:namespaces];
[rootElement removeAttributeForName:@"xsi:schemaLocation"];
[rootElement addAttribute:[NSXMLNode attributeWithName:@"xsi:schemaLocation" stringValue:[NSString stringWithFormat:@"http://www.w3.org/2001/XMLSchema %@", @"/System/Library/Schemas/XMLSchema.xsd"]]];
BOOL vaildXML = [xmlDoc validateAndReturnError:&err];
The schema tag of the document I'm validating:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:myCompany="http://schema.myCompany.com/SomeSchema"
targetNamespace="http://schema.myCompany.com/SomeSchema">
It seems to be having a problem with the w3.org schema location, but not my company's.
The error I'm seeing
error : No such file or directory I/O warning : failed to load external entity "http://www.w3.org/2001/xml.xsd"
Error Domain=NSXMLParserErrorDomain Code=1 UserInfo=0x103051c10 "Element '{http://www.w3.org/2001/XMLSchema}import': Failed to locate a schema at location 'http://www.w3.org/2001/xml.xsd'. Skipping the import. attribute use (unknown), attribute 'ref': The QName value '{http://www.w3.org/XML/1998/namespace}lang' does not resolve to a(n) attribute declaration. attribute use (unknown), attribute 'ref': The QName value '{http://www.w3.org/XML/1998/namespace}lang' does not resolve to a(n) attribute declaration.
Any ideas?
Looking at the Apple docs for the NSXMLDTD class suggests that you do have access to catalogs. However, there seems to be very limited support for defining the catalog to be used. Either you can create a catalog at
/etc/xml/catalog
or set theXML_CATALOG_FILES
environment variable.Once you've got a catalog, you should be able to place an entry into it for the W3 schema along with a local copy. Something like:
This assumes that you have the catalog and the schema in the same directory.
I can't try this myself (lack of time and rusty Cocoa skills) but it should work. If I remember correctly, NSXML is based on libxml2 which certainly supports catalogs. The specifications for catalogs themselves can be found on the OASIS website.