1
votes

I have created two basic XML vocabularies: Address and Person. I have created an Address XSD schema (which doesn't have any dependencies on other schemas) - and this correctly validates an input address.xml doc.

I have created a Person XSD schema which imports the Address XSD. My Person.xml (which is mixed-vocab file) fails it's validation with the following error:

XML validation started.
Checking file:[...]/validator/src/main/resources/person.xml...
Referenced entity at "file:[...]/validator/src/main/resources/person.xsd".
Referenced entity at "file:[...]validator/src/main/resources/address.xsd".
cvc-complex-type.2.4.a: Invalid content was found starting with element 'a:address'. One of '{"urn:person.com.test":address}' is expected. [11] 
XML validation finished.

It appears from the error that the 'Address' type is now mapped (by the import?) to the 'Person' type.

I need to keep my input document in such a format as to ensure two namespaced vocabs are identifiable in the input document (I can't refactor my input document in such a way as to remove the two namespaces - I can't just shove everything into the 'Person' namespace for instance).

What am I doing wrong here ?

Here are my files:

Address.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="urn:address.com.test"
           xmlns="urn:address.com.test"
           xmlns:a="urn:address.com.test"
           elementFormDefault="qualified">
    <xs:element name="address" type="Address" />
    <!-- http://webarchive.nationalarchives.gov.uk/+/http://www.cabinetoffice.gov.uk/media/291370/bs7666-v2-0-xsd-PostCodeType.htm -->
    <xs:simpleType name="PostCodeType">
        <xs:annotation>
            <xs:documentation>complex pattern for postcode, which matches definition, accepted by some parsers is: "(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2})"</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:pattern value="[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][A-Z-[CIKMOV]]{2}"/>
        </xs:restriction>
    </xs:simpleType> 
    <xs:complexType name="Address">
        <xs:sequence>
            <xs:element name="Street_name" type="xs:string" minOccurs="1" maxOccurs="4" />
            <xs:element name="Town_City" type="xs:string"/>
            <xs:element name="County" type="xs:string" minOccurs="0"/>
            <xs:element name="Country" type="xs:string"/>
            <xs:element name="Postcode" type="PostCodeType"/>
        </xs:sequence>
    </xs:complexType>   
</xs:schema>

'Address.xml' - An example of instance document which validates correctly against the schema above:

<?xml version="1.0" encoding="UTF-8"?>
<a:address
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:a='urn:address.com.test'
    xsi:schemaLocation='urn:address.com.test address.xsd'>
    <a:Street_name>10 Downing Street </a:Street_name>
    <a:Town_City>London</a:Town_City>
    <a:Country>UK</a:Country>
    <a:Postcode>SW1A 2AA</a:Postcode>
</a:address>

The Person.xsd: with the import to Address.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="urn:person.com.test"
           xmlns="urn:person.com.test"
           xmlns:p="urn:person.com.test"
           xmlns:a="urn:address.com.test"
           elementFormDefault="qualified">
    <xs:import namespace="urn:address.com.test" schemaLocation="address.xsd"/>
    <xs:element name="person" type="Person" />
    <xs:complexType name="Person">
        <xs:sequence>
            <xs:element name="first_name" type="xs:string" />
            <xs:element name="last_name" type="xs:string"/>

                <xs:element name="address" type="a:Address"/>

        </xs:sequence>
    </xs:complexType>   
</xs:schema>

And the 'Person.xml' - the mixed-vocab document which fails validation:

<?xml version="1.0"?>
<p:person 
    xmlns:p="urn:person.com.test"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:person.com.test person.xsd">
    <p:first_name>Joe</p:first_name>
    <p:last_name>Bloggs</p:last_name>
    <a:address xmlns:a="urn:address.com.test">
        <a:Street_name>10 Downing Street</a:Street_name>
        <a:Town_City>London</a:Town_City>
        <a:Country>UK</a:Country>
        <a:Postcode>SW1A 2AA</a:Postcode>
    </a:address>
</p:person>

I'm using Netbeans 8 to run the validation.

EDIT:

From the accepted answer ; the change I opted for was to change the following in Person.xsd:

From:

<xs:element name="address" type="a:Address"/>

To:

<xs:element ref="a:address"/>

Note that that former refered to the complex type definition "Address" (uppercase 'A' in my example); and the latter refers to the global element definition 'address' (lowercase 'a').

1

1 Answers

1
votes

Doing one of the following will work:

1 Change the XML instance 'Person.xml' as follows:

Change the namespace prefix of the address element from a to p. Specifically, change:

    <a:address xmlns:a="urn:address.com.test">

To:

    <p:address xmlns:a="urn:address.com.test">

Because the address element itself is in the urn:person.com.test namespace even though its type and its children are in the urn:address.com.test namespace.

-or-

2 Change the schema document 'Person.xsd' to use the 'ref' attribute:

From:

    <xs:element name="address" type="a:Address"/>

To:

    <xs:element ref="a:address"/>

Note that that former refered to the complex type definition "Address" (uppercase 'A' in the example above); and the latter refers to the global element definition 'address' (lowercase 'a').