是否允许在XSD中使用多个具有相同名称的元素?

时间:2013-09-04 11:17:01

标签: xml xsd

我正与客户讨论是否允许在具有相同名称的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 (包含根发票元素)

<?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之前更改include元素的顺序以包含Invoice.xsd,则它可以正常工作。

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

但是,如果我使用Stylus Studio XML Professional打开Main.xsd,它看起来没问题。

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

4 个答案:

答案 0 :(得分:2)

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

它不是有效的XSD,因此不符合XSD,但不是因为你问的原因。

为CreditInvoice.xsd中的本地元素Invoice指定的复杂类型无效:它具有xsd:element元素作为xsd:complexType的子元素。我认为这是一个错字,因为你做了什么把示例缩小到可管理的大小。如果将CreditNo的声明移入xsd:sequence元素,则架构文档将变为有效,并且由您提供的三个架构文档定义的架构将成为一致的架构。

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

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

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

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

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

但是,如果我使用Stylus Studio XML Professional打开Main.xsd,它看起来没问题。

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

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

答案 1 :(得分:0)

如果你不确定xml结构,你应该验证它尝试这些网站之一:

我不是绝对确定你的问题,但一般来说你可以使用多个xsd文件。您只需要确保在上层节点中定义允许多个名称空间。

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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