libxmljs2
libxmljs2 copied to clipboard
Validation against multiple schemas
Consider a schema that includes an abstract element form for use by others to extend the schema within the same namespace, such as the following defined by Paul
<!-- main.xsd -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:paul:main"
targetNamespace="urn:paul:main" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Extension" type="myAbstract" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="myAbstract" abstract="true">
<xs:attribute name="extensionName" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z0-9]+"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>
Now Dave defines an extension as
<!-- ext1.xsd -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:dave:ext"
xmlns:main="urn:paul:main" targetNamespace="urn:dave:ext" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:import namespace="urn:paul:main" schemaLocation="main.xsd"/>
<xs:complexType name="Daves-extn">
<xs:complexContent>
<xs:extension base="main:myAbstract">
<xs:sequence>
<xs:element name="extensionElement" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
and John defies his extension as
<!-- ext2.xsd -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:john:ext"
xmlns:main="urn:paul:main" targetNamespace="urn:john:ext" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:import namespace="urn:paul:main" schemaLocation="main.xsd"/>
<xs:complexType name="Johns-extn">
<xs:complexContent>
<xs:extension base="main:myAbstract">
<xs:sequence>
<xs:element name="anInteger" type="xs:integer"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
If an XML instance document is extended by Dave then the following is successful..
<Root xmlns="urn:paul:main" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext1="urn:dave:ext" xsi:schemaLocation="urn:paul:main main.xsd urn:dave:ext ext1.xsd">
<Extension xsi:type="ext1:Daves-extn" extensionName="DAVE001">
<ext1:extensionElement>An Extension</ext1:extensionElement>
</Extension>
</Root>
doc=libxml.parseXmlString(fs.readFileSync("test.xml"))
doc.validate(libxml.parseXmlString(fs.readFileSync("ext1.xsd"))
If an instance document contains extensions from both Dave and John, such as
<Root xmlns="urn:paul:main" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext1="urn:dave:ext" xmlns:ext2="urn:john:ext"
xsi:schemaLocation="urn:paul:main main.xsd urn:dave:ext ext1.xsd urn:john:ext ext2.xsd">
<Extension xsi:type="ext1:Daves-extn" extensionName="DAVE001">
<ext1:extensionElement>An Extension</ext1:extensionElement>
</Extension>
<Extension xsi:type="ext2:Johns-extn" extensionName="JOHN001">
<ext2:anInteger>12</ext2:anInteger>
</Extension>
</Root>
then doc.validate() cannot be used, both extension schemas need to be given and evaluated in the validation.
Since this may be related to libxml, I created issue 229 in their repository.
up