How to define none-namespaced elements within namespaced elements?

In our organization, we usually use XML messages that looks like:

<sev:serviceRequest xmlns:foo="http://foo.com/" xmlns:sev="http://service.com/"> 
    <sev:header>
        <foo:headerElement_1>var1</foo:headerElement_1>
        <foo:headerElement_2>var2</foo:headerElement_2>
        ...
    </sev:header>
    <sev:data>
        <sev:requestData>
            <sev:requestElement_1>var3</sev:requestElement_1>
            <sev:requestElement_2>var4</sev:requestElement_2>
            ...
        </sev:requestData>
    </sev:data>
</sev:serviceRequest>

(The XSDs used are shown below.)

I want to change our XSDs so that they will support messages that looks like:

<sev:serviceRequest xmlns:foo="http://foo.com/" xmlns:sev="http://service.com/"> 
    <sev:header>
        <foo:headerElement_1>var1</foo:headerElement_1>
        <foo:headerElement_2>var2</foo:headerElement_2>
        ...
    </sev:header>
    <sev:data>
        <requestData>
            <requestElement_1>var3</requestElement_1>
            <requestElement_2>var4</requestElement_2>
            ...
        </requestData>
    </sev:data>
</sev:serviceRequest>

So no namespaces will appear below the data element.

I've tried to remove the tns: decleration on the requestData element in service.xsd, but it's required.

I've tried to remove the elementFormDefault="qualified" declaration in all XSDs, but it didn't help.

I've tried to remove the targetNamespace="http://service.com/" decleration in service.xsd, but then ServiceRequest element must NOT have a namespace.

Is it even possible?

service.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://service.com/" xmlns:foo=""http://foo.com/" xmlns:ibmSchExtn="http://www.ibm.com/schema/extensions" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <xsd:include schemaLocation="ServiceData.xsd"/>
        <xsd:import namespace=""http://foo.com/" schemaLocation="Header.xsd"/>
            <xsd:element ibmSchExtn:docRoot="true" name="serviceRequest" type="tns:ServiceRequestType"/>
            <xsd:element ibmSchExtn:docRoot="true" name="serviceResponse" type="tns:ServiceResponseType"/>

            <xsd:complexType name="ServiceRequestType">
                <xsd:sequence>
                    <xsd:element name="header" type="foo:Header"/>
                    <xsd:element maxOccurs="1" minOccurs="0" name="data">
                        <xsd:complexType>
                            <xsd:sequence maxOccurs="1" minOccurs="1">
                                <xsd:element name="requestData" type="tns:requestDataType"/>
                            </xsd:sequence>
                        </xsd:complexType>
                    </xsd:element>
                </xsd:sequence>
            </xsd:complexType>
            ...

header.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://foo.com/" xmlns:foo="http://foo.com/">
    <xsd:complexType name="Header">
        <xsd:sequence>
            <xsd:element name="headerElement_1">
                    <xsd:complexType>
                        <xsd:simpleContent>
                            <xsd:extension base="xsd:string">
                                     <xsd:attribute name="version" type="xsd:string"/>
                            </xsd:extension>
                        </xsd:simpleContent>
                    </xsd:complexType>
            </xsd:element>
            ...

ServiceData.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://service.com/" version="1.0" xmlns:tns="http://service.com/">
    <xsd:complexType name="requestDataType">
        <xsd:sequence>
            <xsd:element maxOccurs="1" minOccurs="1" name="requestElement_1">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                     <xsd:maxLength value="500"/>
                ...

Upvotes: 1

Views: 377

Answers (2)

Ghislain Fourny
Ghislain Fourny

Reputation: 7279

For completeness, here is an alternate and simpler answer that works as well, although it does less of a strict namespace separation for organizing elements (so it does not have my personal preference).

You can add form="unqualified" to the two elements concerned in your original schemas. This is an override on elementFormDefault="qualified" for just these two.

<xsd:element name="requestData" type="tns:requestDataType" form="unqualified"/>
<xsd:element maxOccurs="1" minOccurs="1" name="requestElement_1" form="unqualified">

Upvotes: 0

Ghislain Fourny
Ghislain Fourny

Reputation: 7279

In order to define elements (requestData, requestElement_1) in no namespace, you need to define a schema for them, with no target namespace. It's similar to the original serviceData.xsd, but the element requestData has to be moved there as well and the targetNamespace attribute must be removed:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            attributeFormDefault="qualified"
            elementFormDefault="qualified"
            version="1.0">
    <xsd:element name="requestData" type="requestDataType"/>
    <xsd:complexType name="requestDataType">
        <xsd:sequence>
            <xsd:element maxOccurs="1" minOccurs="1" name="requestElement_1">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                        <xsd:maxLength value="500"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Then, you need to import this schema into service.xsd, not include, which has different semantics. Include would change the namespace of all elements to that of service.xsd instead.

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            elementFormDefault="qualified"
            targetNamespace="http://service.com/"
            xmlns:foo="http://foo.com/"
            xmlns:tns="http://service.com/"
            xmlns:ibmSchExtn="http://www.ibm.com/schema/extensions">
    <xsd:import schemaLocation="ServiceData.xsd"/>
    <xsd:import namespace="http://foo.com/" schemaLocation="header.xsd"/>
    <xsd:element ibmSchExtn:docRoot="true" name="serviceRequest" type="tns:ServiceRequestType"/>

    <xsd:complexType name="ServiceRequestType">
        <xsd:sequence>
            <xsd:element name="header" type="foo:Header"/>
            <xsd:element maxOccurs="1" minOccurs="0" name="data">
                <xsd:complexType>
                    <xsd:sequence maxOccurs="1" minOccurs="1">
                        <xsd:element ref="requestData"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

With these changes (and a few quote fixes in header.xsd), the following document is validated successfully:

<?xml version="1.0" encoding="UTF-8"?>
<sev:serviceRequest
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://service.com/ service.xsd"
   xmlns:sev="http://service.com/"
   xmlns:foo="http://foo.com/"> 
    <sev:header>
        <foo:headerElement_1>var1</foo:headerElement_1>
    </sev:header>
    <sev:data>
        <requestData>
            <requestElement_1>var3</requestElement_1>
        </requestData>
    </sev:data>
</sev:serviceRequest>

Upvotes: 1

Related Questions