2

我正在与客户讨论是否允许在 XSD 中有多个具有相同名称的元素。让我试着解释一下。

CreditInvoice.xsd(在 CreditInvoice 元素中包含一个 Invoice 元素)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="CreditInvoice">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Invoice" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:element name="CreditNo" type="xs:string" />
            <xs:sequence>
              <xs:element name="InvoiceDate" type="xs:date" />
              <xs:element name="InvoiceNo" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Invoice.xsd(包含根 Invoice 元素)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Invoice">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="InvoiceDate" type="xs:date" />
        <xs:element name="InvoiceNo" type="xs:string" />
        <xs:element name="InvoiceReceiver" type="xs:string" />
        <xs:element name="DueDate" type="xs:date" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Main.xsd(包含其他 XSD 文档的主 XSD 文档。)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:include schemaLocation="CreditInvoice.xsd"/>
  <xs:include schemaLocation="Invoice.xsd"/>

  <xs:element name="Invoices">
    <xs:complexType>
      <xs:sequence>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="CreditInvoice" />
          <xs:element ref="Invoice" />
        </xs:choice>
      </xs:sequence>      
    </xs:complexType>
  </xs:element>

</xs:schema>

当我在例如 CAM 模板编辑器 ( http://www.cameditor.org ) 中打开 Main.xsd 时,Main.xsd 中 Invoice 的元素引用使用 CreditInvoice.xsd 中定义的 Invoice 元素而不是 Invoice.xsd 中定义的元素客户正在努力实现的目标。

如果我将包含元素的顺序更改为在 CreditInvoice.xsd 之前包含 Invoice.xsd,则它可以正常工作。

客户说它是有效的 XSD。但我不知道是不是。它(Main.xsd)应该如何知道它应该引用哪个 Invoice 元素?我使用另一个工具看到了同样的错误。

但是,如果我使用 Stylus Studio XML Professional 打开 Main.xsd,它看起来还不错。

谁能告诉我哪种行为是正确的?

4

4 回答 4

2

客户说它是有效的 XSD。但我不知道是不是。

它不是有效的 XSD,因此不符合 XSD,但不是出于您要询问的原因。

CreditInvoice.xsd 中为本地元素指定的复杂类型Invoice无效:它有一个 xsd:element 元素作为 xsd:complexType 的子元素。我认为这是由于您将示例缩减到可管理的大小所做的任何事情而导致的拼写错误。如果将 CreditNo 的声明移到 xsd:sequence 元素中,则架构文档变为有效,并且您提供的三个架构文档定义的架构将成为一致的架构。

关于将本地元素与顶级/全局元素同名的问题,您的客户毫无疑问是正确的。它是合法的,它的目的是合法的,它是 XSD 设计的重要组成部分。(@Augusto 可能是对的,它可能会让人感到困惑;设计师在使用此功能时当然应该小心。但它绝对是合规的。)

它(Main.xsd)应该如何知道它应该引用哪个 Invoice 元素?我使用另一个工具看到了同样的错误。

你说“同样的错误”,但你没有描述错误信息。也许您的意思是另一个工具似乎也将<xs:element ref="Invoice" />Main.xsd 中的作为对 CreditInvoice.xsd 中定义的 Invoice 的引用,而不是对 Invoice.xsd 中定义的 Invoice 的引用。

任何对元素的引用,如<xs:element ref="Invoice" />Main.xsd 中的 ,都是对具有匹配名称的顶级(也称为全局)元素的引用。在一个一致的模式中,总是最多有一个这样的元素。因此,当从示例中的各种模式文档中的声明构造模式时,任何符合要求的处理器都会知道Invoice可以作为子元素出现的元素是 Invoice.xsd 中声明Invoices的顶级元素。Invoice它不能是InvoiceCreditInvoice.xsd 中声明的元素,因为该元素是该元素的复杂类型的本地CreditInvoice元素。像任何本地元素一样,它可以在声明的地方使用,而不能在其他地方使用。

如果您说您提到的工具将 Main.xsd 中的元素引用视为对 CreditInvoice.xsd 中 CreditInvoice 本地声明的 Invoice 的引用是正确的,那么您刚刚发现了这些工具中的错误。如果您关心这些工具并对供应商有任何善意,您应该报告问题,以便他们修复它。

但是,如果我使用 Stylus Studio XML Professional 打开 Main.xsd,它看起来还不错。

谁能告诉我哪种行为是正确的?

规范可以告诉你;可靠的书籍可以告诉你;可靠的工具可以告诉你(比在规范中阅读要少得多)。

于 2013-09-04T14:52:13.283 回答
0

不允许模式包含两个具有相同名称的全局元素声明(即相同的本地名称和目标名称空间)。请参阅规范中的第 2.5 节。

于 2013-09-04T13:33:25.117 回答
0

如果您不确定 xml 结构,您应该验证它尝试以下站点之一:

我不确定您的问题,但通常您可以使用多个 xsd 文档。您只需要确保在上层节点中定义允许多个命名空间。

于 2013-09-04T11:43:21.057 回答
0

是的,你可以,但从语义的角度来看,我会尽量避免这种情况,因为这意味着你用相同的名称调用了 2 个不同的东西,这总是会打开混乱的大门。

您在上面显示的内容将不起作用,因为您没有为每种类型指定命名空间,并且您需要这样做,因为您有 2 个具有相同名称的元素(参考部分将失败)。如果您指定命名空间并配置解析器以正确处理命名空间(祝您好运,因为它通常非常复杂)。

不能拥有的是同一个 xsd 中具有相同名称的两种类型。

于 2013-09-04T12:59:31.660 回答