如何解决为具有多个命名空间的 XML 创建 XSD
我将收到如下所示的 XML 文档:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<EFOCE>
<CustomerLegalEntity>
<FullName>Bob Smith</FullName>
</CustomerLegalEntity>
<Extension xmlns:d3p1="CactusExtension">
<CustomerPersonNo>100555</CustomerPersonNo>
<DeliveryExtensions>
<DeliveryExtension i:type="d3p1:DeliveryExtension">
<ContractCode>123456</ContractCode>
</DeliveryExtension>
</DeliveryExtensions>
</Extension>
</EFOCE>
</root>
我无法以任何方式更改 XML 文档。我现在必须编写一个模式文件(或多个模式文件)来验证这些 XML 文档。在 BizTalk 中,我尝试了“添加生成的项目”功能,它会给我这个单一的 XSD 文件:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns:d3p1="CactusExtension"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="EFOCE">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerLegalEntity">
<xs:complexType>
<xs:sequence>
<xs:element name="FullName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Extension">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerPersonNo" type="xs:unsignedInt" />
<xs:element name="DeliveryExtensions">
<xs:complexType>
<xs:sequence>
<xs:element name="DeliveryExtension">
<xs:complexType>
<xs:sequence>
<xs:element name="ContractCode" type="xs:unsignedInt" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
但是这个 XSD 文件是不正确的,因为它不会验证 XML。当我尝试根据生成的 XSD 验证 XML 文件时,它在 BizTalk 中给了我以下错误消息:
error BEC2004: This is an invalid xsi:type 'CactusExtension:DeliveryExtension'.
它也给了我这个警告,但我认为这不是主要问题:
warning BEC1007: Node "<Schema>" - Target namespace is empty.
我猜问题是元素 EFOCE 和 ContractCode 属于空命名空间“”,但元素 DeliveryExtension 属于命名空间 CactusExtension。我试图在它自己的 XSD 文件中定义 DeliveryExtension,然后从主 XSD 中包含它。这对于该元素来说很顺利,但随后对于不在命名空间 CactusExtension 中的子元素 ContractCode 出现其他错误。
如何编写 XSD 文件?
根据 Michael Kay 的回答添加:
我现在已经像这样修改了主架构文件(引入了 xs:import
并更改了元素 DeliveryExtension):
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns:d3p1="CactusExtension"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="CactusExtension" schemaLocation="DeliveryExtension.xsd"/>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="EFOCE">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerLegalEntity">
<xs:complexType>
<xs:sequence>
<xs:element name="FullName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Extension">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerPersonNo" type="xs:unsignedInt" />
<xs:element name="DeliveryExtensions">
<xs:complexType>
<xs:sequence>
<xs:element name="DeliveryExtension" type="d3p1:DeliveryExtension"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
并且我添加了一个单独的架构文件 DeliveryExtension.xsd,其内容如下:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="CactusExtension"
xmlns="CactusExtension"
elementFormDefault="qualified">
<xs:complexType name="DeliveryExtension">
<xs:sequence>
<xs:element name="ContractCode" type="xs:unsignedInt" />
</xs:sequence>
</xs:complexType>
</xs:schema>
当我尝试针对 XSD 验证 XML 文件时,我现在收到以下错误消息(以及与以前相同的警告):
error BEC2004: The element 'DeliveryExtension' has invalid child element 'ContractCode'. List of possible elements expected: 'ContractCode' in namespace 'CactusExtension'.
我认为出现这个错误是因为在 XML 文件中,ContractCode 不属于命名空间 CactusExtension。
有没有办法让元素 ContractCode 得到验证?
解决方法
架构正确,但不完整。您的实例文档包含对架构类型 Q{CactusExtension}DeliveryExtension
的引用,但架构生成器无法知道在哪里可以找到此类型。
我的猜测(但这只是一个猜测,模式生成器不可能做出这样的猜测)是您想要定义一个复杂类型
<xs:complexType name="DeliveryType">
<xs:sequence>
<xs:element name="ContractCode" type="xs:unsignedInt" />
</xs:sequence>
</xs:complexType>
目标命名空间 = CactusExtension
。由于这是与主架构文档不同的命名空间,因此它需要进入通过 xs:import
链接的单独架构文档。
任何模式生成器都不会为您提供捕获数据模型所有语义的输出。这只是为您节省一些繁重工作的起点。
=== 稍后 ===
您已实施此建议并将其添加到您的问题中。但是你得到了一个错误,因为元素 ContractCode 的声明现在在 CactusExtension 命名空间中。您需要将元素声明为 <xs:element ref="ContractCode"/>
,并将元素声明移至无命名空间架构文档中的全局声明;您还需要添加一个 xs:import 以使此引用有效。
=== 稍后 ===
我不喜欢给人们提供完整的代码,我更喜欢给出建议和鼓励,但既然你在苦苦挣扎,这里有两个架构文档:
root.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:import namespace="CactusExtension" schemaLocation="DeliveryExtension.xsd"/>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="EFOCE">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerLegalEntity">
<xs:complexType>
<xs:sequence>
<xs:element name="FullName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Extension">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerPersonNo" type="xs:unsignedInt"/>
<xs:element name="DeliveryExtensions">
<xs:complexType>
<xs:sequence>
<xs:element name="DeliveryExtension"
type="cactus:DeliveryExtension" xmlns:cactus="CactusExtension"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ContractCode" type="xs:unsignedInt"/>
</xs:schema>
DeliveryExtension.xsd
<?xml version="1.0" encoding="utf-16"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="CactusExtension"
elementFormDefault="qualified">
<xs:import schemaLocation="root.xsd"/>
<xs:complexType name="DeliveryExtension">
<xs:sequence>
<xs:element ref="ContractCode"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
您的实例文档对此模式有效(使用在 Oxygen 下运行的 Saxon 模式处理器进行测试)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。