我正与客户讨论是否允许在具有相同名称的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,它看起来没问题。
有谁能告诉我哪种行为是正确的?
答案 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节。