XSD 确保每个枚举值只能作为属性出现一次
XSD assuring that each enumeration value can only occur once as attribute
假设我有一个架构来定义文章列表。这些文章中的每一篇都有一个长名称列表,每个名称对应一种已知语言。语言是个体长名级别的属性。
我想保证两件事:
- 语言属性只能有几个预先确定的值之一(使用枚举解决)。
- 在每个 list 长名称中,语言属性的给定值只能出现一次。每篇文章我只能有一个英文长名,一个德文长名,一个法文长名等等
在另一个 post (link) 之后,我在 longName 级别实现了一个唯一约束。它将满足#1,但不满足#2。如果我在同一个 longNames 元素中有两倍于 longName 属性的 'EN',它将认为 xml 有效。
原始样本XML
<article>
<articleNumber>3019</articleNumber>
<longNames>
<longName language="EN">
<description>A French Omelette with Cheese</description>
</longName>
<longName language="FR">
<description>Un omelette DU(???) fromage</description>
</longName>
</longNames>
</article>
原始XSD架构
<xs:complexType name="ArticleType">
<xs:sequence>
<xs:element name="articleNumber" type="xs:integer" />
<xs:element type="bl:LongNamesType" name="longNames" />
<xs:element type="bl:ShortNameType" name="shortName" maxOccurs="3" />
<xs:element type="bl:AllergensType" name="allergens" maxOccurs="3" />
<xs:element type="bl:IngredientsType" name="ingredients" maxOccurs="3" />
<xs:element type="bl:PictureType" name="picture" maxOccurs="3" />
<xs:element name="barcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LongNamesType">
<xs:sequence>
<xs:element name="longName" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<!-- <xs:element type="bl:LanguageType" name="language" /> -->
<xs:element name="description" type="xs:string" />
</xs:sequence>
<xs:attribute name="language" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="EN" />
<xs:enumeration value="FR" />
<xs:enumeration value="DE" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<xs:unique name="uniqueLongNameLanguage">
<xs:selector xpath="longNames" />
<xs:field xpath="@language" />
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
谁能帮我弄清楚我做错了什么?
编辑:感谢 Yitzak Khabinsky 和 Michael Kay,我设法找到了以下可行的解决方案。诚然,它有点混合了多种风格。感谢所有回复的人!
改进XSD
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"
xmlns:bl="urn:inventoryinput"
targetNamespace="urn:inventoryinput">
<xs:element name="inventory" type="bl:InventoryType" />
<xs:complexType name="InventoryType">
<xs:sequence>
<xs:element type="bl:ArticleType" name="article" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArticleType">
<xs:sequence>
<xs:element name="articleNumber" type="xs:integer" />
<xs:element ref="bl:longNames" minOccurs="0" />
<xs:element name="barcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:element name="longNames">
<xs:complexType>
<xs:sequence>
<xs:element ref="bl:longName" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueLongNameLanguage">
<xs:selector xpath="bl:longName" />
<xs:field xpath="@language" />
</xs:unique>
</xs:element>
<xs:element name="longName" >
<xs:complexType>
<xs:sequence>
<xs:element name="description" type="xs:string" />
</xs:sequence>
<xs:attribute name="language" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NL" />
<xs:enumeration value="FR" />
<xs:enumeration value="DE" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
...
修改了 XML 示例
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:inventoryinput">
<article>
<articleNumber>3019</articleNumber>
<longNames>
<longName language="NL">
<description>DE TROG Ardeens bruin brood Bio 600g</description>
</longName>
<longName language="FR">
<description>DE TROG pain ardennais complet Bio 600g</description>
</longName>
</longNames>
请尝试以下解决方案。
输入XML
<article>
<articleNumber>3019</articleNumber>
<longNames>
<longName language="EN">
<description>A French Omelette with Cheese</description>
</longName>
<longName language="FR">
<description>Un omelette DU(???) fromage</description>
</longName>
</longNames>
</article>
XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="article">
<xs:complexType>
<xs:sequence>
<xs:element ref="articleNumber"/>
<xs:element ref="longNames"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="articleNumber" type="xs:integer"/>
<xs:element name="longNames">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="longName"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueLongNameLanguage">
<xs:selector xpath="longName"/>
<xs:field xpath="@language"/>
</xs:unique>
</xs:element>
<xs:element name="longName">
<xs:complexType>
<xs:sequence>
<xs:element ref="description"/>
</xs:sequence>
<xs:attribute name="language" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="EN"/>
<xs:enumeration value="FR"/>
<xs:enumeration value="DE"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="description" type="xs:string"/>
</xs:schema>
假设我有一个架构来定义文章列表。这些文章中的每一篇都有一个长名称列表,每个名称对应一种已知语言。语言是个体长名级别的属性。
我想保证两件事:
- 语言属性只能有几个预先确定的值之一(使用枚举解决)。
- 在每个 list 长名称中,语言属性的给定值只能出现一次。每篇文章我只能有一个英文长名,一个德文长名,一个法文长名等等
在另一个 post (link) 之后,我在 longName 级别实现了一个唯一约束。它将满足#1,但不满足#2。如果我在同一个 longNames 元素中有两倍于 longName 属性的 'EN',它将认为 xml 有效。
原始样本XML
<article>
<articleNumber>3019</articleNumber>
<longNames>
<longName language="EN">
<description>A French Omelette with Cheese</description>
</longName>
<longName language="FR">
<description>Un omelette DU(???) fromage</description>
</longName>
</longNames>
</article>
原始XSD架构
<xs:complexType name="ArticleType">
<xs:sequence>
<xs:element name="articleNumber" type="xs:integer" />
<xs:element type="bl:LongNamesType" name="longNames" />
<xs:element type="bl:ShortNameType" name="shortName" maxOccurs="3" />
<xs:element type="bl:AllergensType" name="allergens" maxOccurs="3" />
<xs:element type="bl:IngredientsType" name="ingredients" maxOccurs="3" />
<xs:element type="bl:PictureType" name="picture" maxOccurs="3" />
<xs:element name="barcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LongNamesType">
<xs:sequence>
<xs:element name="longName" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<!-- <xs:element type="bl:LanguageType" name="language" /> -->
<xs:element name="description" type="xs:string" />
</xs:sequence>
<xs:attribute name="language" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="EN" />
<xs:enumeration value="FR" />
<xs:enumeration value="DE" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<xs:unique name="uniqueLongNameLanguage">
<xs:selector xpath="longNames" />
<xs:field xpath="@language" />
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
谁能帮我弄清楚我做错了什么?
编辑:感谢 Yitzak Khabinsky 和 Michael Kay,我设法找到了以下可行的解决方案。诚然,它有点混合了多种风格。感谢所有回复的人!
改进XSD
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"
xmlns:bl="urn:inventoryinput"
targetNamespace="urn:inventoryinput">
<xs:element name="inventory" type="bl:InventoryType" />
<xs:complexType name="InventoryType">
<xs:sequence>
<xs:element type="bl:ArticleType" name="article" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArticleType">
<xs:sequence>
<xs:element name="articleNumber" type="xs:integer" />
<xs:element ref="bl:longNames" minOccurs="0" />
<xs:element name="barcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:element name="longNames">
<xs:complexType>
<xs:sequence>
<xs:element ref="bl:longName" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueLongNameLanguage">
<xs:selector xpath="bl:longName" />
<xs:field xpath="@language" />
</xs:unique>
</xs:element>
<xs:element name="longName" >
<xs:complexType>
<xs:sequence>
<xs:element name="description" type="xs:string" />
</xs:sequence>
<xs:attribute name="language" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NL" />
<xs:enumeration value="FR" />
<xs:enumeration value="DE" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
...
修改了 XML 示例
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:inventoryinput">
<article>
<articleNumber>3019</articleNumber>
<longNames>
<longName language="NL">
<description>DE TROG Ardeens bruin brood Bio 600g</description>
</longName>
<longName language="FR">
<description>DE TROG pain ardennais complet Bio 600g</description>
</longName>
</longNames>
请尝试以下解决方案。
输入XML
<article>
<articleNumber>3019</articleNumber>
<longNames>
<longName language="EN">
<description>A French Omelette with Cheese</description>
</longName>
<longName language="FR">
<description>Un omelette DU(???) fromage</description>
</longName>
</longNames>
</article>
XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="article">
<xs:complexType>
<xs:sequence>
<xs:element ref="articleNumber"/>
<xs:element ref="longNames"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="articleNumber" type="xs:integer"/>
<xs:element name="longNames">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="longName"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueLongNameLanguage">
<xs:selector xpath="longName"/>
<xs:field xpath="@language"/>
</xs:unique>
</xs:element>
<xs:element name="longName">
<xs:complexType>
<xs:sequence>
<xs:element ref="description"/>
</xs:sequence>
<xs:attribute name="language" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="EN"/>
<xs:enumeration value="FR"/>
<xs:enumeration value="DE"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="description" type="xs:string"/>
</xs:schema>