【问题标题】:Create XSD for XML with multiple namespaces为具有多个命名空间的 XML 创建 XSD
【发布时间】:2021-06-13 21:49:45
【问题描述】:

我将收到如下所示的 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 "&lt;Schema&gt;" - 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 元素?

【问题讨论】:

  • 基本上,您的命名空间前缀 d3p1 没有在您的 XML 根目录中定义,因此您的 XML 甚至无效。这个警告也是一个线索,你错过了一个命名空间。因此,目前除了标准 XMLSchema 命名空间之外,您没有“多个命名空间”。
  • P.S.如果您确实在其中添加了默认命名空间,并且使用另一个命名空间定义了命名空间前缀 d3p1,您会发现当您生成项目时,您将拥有多个 XSD 文件,其中一个通过 Import 引用另一个根目录,因为您只能每个 XSD 有一个命名空间。
  • @Dijkgraaf 你发明了一个不存在的规则。格式正确和有效性都不需要在根元素上声明命名空间。
  • @Dijkgraaf 我不知道需要什么才能很好地使用 Biztalk,但是您关于 XML 无效的建议是完全不正确的。

标签: xml xsd biztalk xml-namespaces


【解决方案1】:

架构正确,但不完整。您的实例文档包含对架构类型 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 命名空间中。您需要将元素声明为&lt;xs:element ref="ContractCode"/&gt;,并将元素声明移动为无命名空间模式文档中的全局声明;您还需要添加一个 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 架构处理器进行测试)。

【讨论】:

  • 非常感谢您的帮助。不幸的是,我无法让它工作。我根据您的建议更新了我的问题。我是否误解了您的一些建议,或者我只需要在某个地方添加一点 tweek 才能使其发挥作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 2014-02-07
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多