具有相同名称但不同属性值的元素序列的 XML 模式?
如何为这样的实例文档指定 XML 模式:
How can I specify an XML schema for an instance document like this:
<productinfo>
<!-- other stuff -->
<informationset type="Manufacturer">
<!-- content not relevant -->
</informationset>
<informationset type="Ingredients">
<!-- content not relevant -->
</informationset>
</productinfo>
也就是说,一个productinfo"元素包含两个informationset"子元素的序列,第一个有@type="Manufacturer"
,第二个有@type="Ingredients"
?
that is, a "productinfo" element containing a sequence of two "informationset" children, the first having @type="Manufacturer"
and the second having @type="Ingredients"
?
注意 正如 Serge 指出的那样,这个答案是不正确的.
NOTE this answer is incorrect, as Serge pointed out.
使用 xerces 进行测试会出现以下错误:type.xsd:3:21: cos-element-consistent: Error for type '#AnonType_productinfo'.具有不同类型的名称为informationset"的多个元素出现在模型组中.
cos-element-consistent.
Testing with xerces gives this error: type.xsd:3:21: cos-element-consistent: Error for type '#AnonType_productinfo'. Multiple elements with name 'informationset', with different types, appear in the model group.
There's more detail in the spec for cos-element-consistent.
但是有一个解决方案,类似于下面 Marc 的回答,但仍然使用类型.如果它们在由其他类型扩展的超类型的 minOccurs/maxOccurs 列表中,则可以多次出现相同的不同类型.也就是说,就像 java 或 C# 中的多态类列表一样.这克服了上述问题,因为尽管该元素名称可以在 xml 中出现多次,但在 xsd 中只出现一次.
But there's a solution, similar to Marc's answer below, but still using types. It is possible to have multiple occurrences of the same with different types, if they are in a minOccurs/maxOccurs list of a supertype, which is extended by the other types. That is, just like a list of polymorphic classes in java or C#. This overcomes the problem above because although that element name can appear many times in the xml, it only appears once in the xsd.
这里是示例 xsd 和 xml - 这次用 xerces 测试!:
Here is example xsd and xml - tested with xerces this time!:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="productinfo">
<xs:complexType>
<xs:sequence>
<xs:element name="informationset" type="supertype" minOccurs="2" maxOccurs="2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="supertype">
</xs:complexType>
<xs:complexType name="Manufacturer">
<xs:complexContent>
<xs:extension base="supertype">
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Ingredients">
<xs:complexContent>
<xs:extension base="supertype">
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
<productinfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<informationset xsi:type="Manufacturer"></informationset>
<informationset xsi:type="Ingredients"></informationset>
</productinfo>
注意:您无法控制不同类型的顺序,或者每种类型出现的次数(每种都可以出现一次、多次或根本不出现)——就像java 或 C# 中的多态类列表.但是您至少可以指定整个列表的确切长度(如果您愿意).
NOTE: You can't control the order of the different types, or how many times each type occurs (each could appear once, many times, or not appear at all) - just as with a list of polymorphic classes in java or C#. But you can at least specify at exact length of the list overall (if you like).
例如,我将上面的示例限制为恰好两个元素,但没有设置顺序(即 Manufacturer 可以是第一个,或者 Ingredients 可以是第一个);并且未设置重复次数(即它们可以都是 Manufacturer,或者都是 Ingredients,或者两者之一).
For example, I've restricted the above example to exactly two elements, but the order is not set (i.e. Manufacturer could be first, or Ingredients could be first); and number of repetitions is not set (i.e. they could both be Manufacturer, or both Ingredients, or one of each).
您可以使用 XML Schema type,如下所示:
You can, with XML Schema type, as in:
<productinfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<informationset xsi:type="Manufacturer"></informationset>
<informationset xsi:type="Ingredients"></informationset>
</productinfo>
XSD 为每个定义了单独的复杂类型:
And the XSD defines separate complex types for each one:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="productinfo">
<xs:complexType>
<xs:sequence>
<xs:element name="informationset" type="Manufacturer"/>
<xs:element name="informationset" type="Ingredients"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Manufacturer">
</xs:complexType>
<xs:complexType name="Ingredients">
</xs:complexType>
</xs:schema>
这是xsi:type
的特殊情况.一般来说,不要认为你可以在同名元素中指定属性具有不同的值,因为它们是同一个元素的不同定义.
This is a special case for xsi:type
. In general, don't think you can specify attributes to have different values in elements of the same name, because they are different definitions of the same element.
我不是 100% 清楚确切原因——有人知道规范的相关部分吗?
I'm not 100% clear on the precise reason - anyone know the relevant part of the spec?