如何在命名空间元素中定义非命名空间元素?

时间:2016-06-14 10:01:39

标签: xml xsd xml-namespaces

在我们的组织中,我们通常使用看起来像这样的XML消息:

<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>

(使用的XSD如下所示。)

我想更改我们的XSD,以便它们支持看起来像这样的消息:

<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>

因此数据元素下方不会出现任何名称空间。

我试图删除service.xsd中requestData元素的tns:decleration,但它是必需的。

我试图删除所有XSD中的elementFormDefault =“qualified”声明,但它没有帮助。

我试图删除service.xsd中的targetNamespace =“http://service.com/”decleration,但是ServiceRequest元素必须没有命名空间。

甚至可能吗?

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"/>
                ...

2 个答案:

答案 0 :(得分:1)

为了在没有名称空间的情况下定义元素(requestData,requestElement_1),您需要为它们定义一个模式,没有目标名称空间。它与原始serviceData.xsd类似,但必须将元素requestData移动到那里,并且必须删除targetNamespace属性:

<?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>

然后,您需要将此架构导入service.xsd,而不是include,它具有不同的语义。 Include会将所有元素的命名空间改为service.xsd。

<?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>

通过这些更改(以及header.xsd中的一些引用修复),以下文档已成功验证:

<?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>

答案 1 :(得分:0)

为了完整性,这里有一个替代的,更简单的答案,虽然它对组织元素没有严格的命名空间分离(因此它没有我的个人偏好)。

您可以添加form =&#34;不合格&#34;到原始模式中涉及的两个元素。这是对elementFormDefault =&#34;限定&#34;的覆盖。仅仅这两个。

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