如何在命名空间元素中定义 none-命名空间元素?
How to define none-namespaced elements within namespaced elements?
在我们的组织中,我们通常使用 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"/>
...
为了在没有命名空间的情况下定义元素(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>
为了完整起见,这里有一个替代的、更简单的答案,它也可以工作,尽管它在组织元素时没有严格的命名空间分离(所以它不符合我个人的偏好)。
您可以将 form="unqualified" 添加到原始模式中涉及的两个元素。这是对这两个的 elementFormDefault="qualified" 的覆盖。
<xsd:element name="requestData" type="tns:requestDataType" form="unqualified"/>
<xsd:element maxOccurs="1" minOccurs="1" name="requestElement_1" form="unqualified">
在我们的组织中,我们通常使用 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"/>
...
为了在没有命名空间的情况下定义元素(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>
为了完整起见,这里有一个替代的、更简单的答案,它也可以工作,尽管它在组织元素时没有严格的命名空间分离(所以它不符合我个人的偏好)。
您可以将 form="unqualified" 添加到原始模式中涉及的两个元素。这是对这两个的 elementFormDefault="qualified" 的覆盖。
<xsd:element name="requestData" type="tns:requestDataType" form="unqualified"/>
<xsd:element maxOccurs="1" minOccurs="1" name="requestElement_1" form="unqualified">