1

I'm trying to use namespaces on a xml file composed by more files.

XML Schema

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
    version="1.0"
    attributeFormDefault="unqualified"
    elementFormDefault="qualified"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="urn:mynamespace"
    targetNamespace="urn:mynamespace">

    <xsd:element name="main_element" type="typeMainElement" />

    <xsd:complexType name="typeMainElement">
        <xsd:sequence>
            <xsd:element name="inner_element" type="typeInnerElement" />
        </xsd:sequence>
    <xsd:attribute name="test_attribute" type="xsd:string" use="required" />
    </xsd:complexType>

    <xsd:complexType name="typeInnerElement">
        <xsd:sequence>
            <xsd:element name="description" type="xsd:string" minOccurs="0" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Main XML

<main_element test_attribute="value"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns="urn:mynamespace">
    <inner_element>
        <description>Test</description>
    </inner_element>
</main_element>

Validating the XML with the XML Schema works perfectly. But if I try to outsource some part of the XML, relying on XInclude then nothing works anymore.

Splitted XML

<main_element test_attribute="value"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns="urn:mynamespace">
    <xi:include href="simple_part.xml" />
</main_element>

Included XML

<inner_element>
    <description>Test</description>
</inner_element>

Trying to validate the Splitted XML returns the error:

simple_part.xml:1: element inner_element: Schemas validity error : Element 'inner_element': This element is not expected. Expected is ( {urn:mynamespace}inner_element ).

simple_main_element.xml fails to validate

It seems that when including I loose the namespace inheriting, so the included content doesn't have a namespace anymore.

-- How do I solve this, without adding namespace prefixes everywhere? --

-- ADDED QUESTION: how to solve the problem also in the case where the inclusion is from another directory, like <xi:include href="subdir/simple_part.xml" />?

Community
  • 1
  • 1
Kamafeather
  • 8,663
  • 14
  • 69
  • 99

1 Answers1

1

Well, it seems that you have a few modifications to perform:

1) In your XML fragment, you need to declare the same namespace as as the "master" document

 <inner_element xmlns="urn:mynamespace">
   <description>Test</description>
 </inner_element>

2) In the resulting document, an xml:base attribute is automatically set (see XInclude spec, §4.5.5 and C.1) so that you have to declare it in your schema by declaring this attribute and importing the xml namespace like so:

   <xsd:schema
       version="1.0"
       attributeFormDefault="unqualified"
       elementFormDefault="qualified"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns="urn:mynamespace"
       targetNamespace="urn:mynamespace">

       <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd" />

       <xsd:element name="main_element" type="typeMainElement" />

       <xsd:complexType name="typeMainElement">
           <xsd:sequence>
               <xsd:element name="inner_element" type="typeInnerElement" />
           </xsd:sequence>
       <xsd:attribute name="test_attribute" type="xsd:string" use="required" />
       </xsd:complexType>

       <xsd:complexType name="typeInnerElement">
           <xsd:sequence>
               <xsd:element name="description" type="xsd:string" minOccurs="0" />
           </xsd:sequence>
           <xsd:attribute ref="xml:base"/>
       </xsd:complexType>
   </xsd:schema>

Alternative solution with entities

You need to declare (parsed) entities in a DOCTYPE at the beginning of the "master" document, and use the reference instead of the <xi:include> like so:

<?xml version="1.0"?>
<!DOCTYPE main_element [
  <!ENTITY simple_part SYSTEM "simple_part.xml">
]>
<main_element test_attribute="value"
     xmlns:xi="http://www.w3.org/2001/XInclude"
     xmlns="urn:mynamespace">
   <!-- call a reference instead of xi:include -->
   &simple_part_1;
</main_element>

The simple_part.xml will be exactely what you required in the original post:

<inner_element>
  <description>Test</description>
</inner_element>
potame
  • 7,597
  • 4
  • 26
  • 33
  • yes it does. I was already able to solve it adding the namespace indeed. The solution is ok but I want to _avoid the additional `xml:base` attribute into the the schema_ (in my opinion that's not something related to the date definition but just a workaround that add dirtiness [am not blaming you; I know that's the common solution ;) ]). Anyway I added a question relative to the inclusion URI, if you want to expand your answer. – Kamafeather Mar 13 '15 at 10:09
  • @Kamafeather It just came to my mind: if you don't want to modify your schema, perhaps you can use a good old entity reference? – potame Mar 14 '15 at 16:18
  • I didn't get what an entity reference can do for me -_-' – Kamafeather Mar 18 '15 at 09:47
  • @Kamafeather I haved added the "entity" solution to my answer. – potame Mar 18 '15 at 13:11
  • Oh thanks, now I got it. Even if it doesn't suit my case (I solved just manually removing the `xml:base` attribute, cause in my context will not be needed). But good to know anyway!. – Kamafeather Mar 18 '15 at 15:41