Home > Back-end >  Use complex types in imported XSD from importing XSD without changing existing XMLs
Use complex types in imported XSD from importing XSD without changing existing XMLs

Time:09-23

Question: Is it possible to import complexTypes into a schema without having to declare both namespaces in the resulting XML file?


I know that similar questions have been asked, but none I've seen have covered my specific need which takes a bit to explain:

Let's say in a prior version of a piece of software we shipped a schema that would look like this example:

specific.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/specific" xmlns="http://test.com/specific" elementFormDefault="qualified" version="1.0">
    <xs:complexType name="testType">
        <xs:sequence>
            <xs:element name="testSubElement" type="testSubElement"></xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="testSubElement"></xs:complexType>

    <element name="testType" type="common:testType"></element>
</xs:schema>

to be used like this:

file.xml

<?xml version="1.0" encoding="UTF-8"?>
<testType xmlns="http://test.com/specific" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://test.com/specific specific.xsd">
    <testSubElement/>
</testType>

We actually had several similar schemas, so later we decided to pull out the common definitions into a core file and import that file into the relevant schemas:

common.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/common" xmlns="http://test.com/common" elementFormDefault="qualified" version="1.0">
    <xs:complexType name="testType">
        <xs:sequence>
            <xs:element name="testSubElement" type="testSubElement"></xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="testSubElement"></xs:complexType>
</xs:schema>

specific.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/specific" 
    elementFormDefault="qualified" xmlns:specific="http://test.com/specific" xmlns:common="http://test.com/common" version="1.0">
    
    <import namespace="http://test.com/common" schemaLocation="common.xsd"/>

    <element name="testType" type="common:testType"></element>
</schema>

However, now we're getting issues with existing files not validating correctly like they used to:

$ xmllint --schema specific.xsd myFile.xml
<?xml version="1.0" encoding="UTF-8"?>
<testType xmlns="http://test.com/specific" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://test.com/specific specific.xsd">
    <testSubElement/>
</testType>
myFile.xml:4: element testSubElement: Schemas validity error : Element '{http://test.com/specific}testSubElement': This element is not expected. Expected is ( {http://test.com/common}testSubElement ).
myFile.xml fails to validate 

Is it possible for us to modify our schema into this common/specific pattern without needing to make changes to the XML files conforming to the schema, while preserving the validation? How would it be done?

CodePudding user response:

If you want to use the same namespace for elements defined in both schema documents, then both schema documents should have the same target namespace and you should use xs:include rather than xs:import to combine them.

  • Related