[英]XSD different types same name
我是 XML / XSD 的新手,所以這對你們大多數人來說可能是一個簡單的問題,但我無法找到解決以下問題的可行解決方案。
我有一個像:
<?xml version="1.0" encoding="UTF−8"?>
<gallery>
<character >
<name>Luke Skywalker</name>
<species>Human</species>
<language>Basic</language>
<home>Tatooine</home>
</character>
<character >
<name>Chewbacca</name>
<species>Wookie</species>
<language>Shyriiwook</language>
<home>Kashyyyk</home>
<battlecry>AARGH!</battlecry>
</character>
</gallery>
這是一個畫廊,其中第二個角色具有額外的元素戰吼(它是伍基元素,另一個元素是星球大戰類型)
我有一個 XSD,我在其中定義了 wookieType 和 starWarsEntity
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="starWarsEntity">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="species" type="xsd:string"/>
<xsd:element name="language" type="xsd:string"/>
<xsd:element name="home" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="wookieType">
<xsd:complexContent>
<xsd:extension base="starWarsEntity">
<xsd:sequence>
<xsd:element name="battlecry" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="character">
<xsd:choice>
<xsd:element name="wookieType" type="wookieType" />
<xsd:element name="starWarsEntity" type="starWarsEntity"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="gallery">
<xsd:sequence>
<xsd:element name="character" type="character" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="gallery" type="gallery">
</xsd:element>
</xsd:schema>
我想要的是一個畫廊,其中包含可以是 wookyType 或 starWarsEntity 類型的字符
我在鏈接上在線驗證了這兩個文件,您可以在那里看到這兩個文件,但出現一些錯誤:
發現以元素“名稱”開頭的無效內容。 '{wookieType, starWarsEntity}' 之一是預期的。
我做錯了什么,兩個文件都有效?
您聲明了gallery
包含一個character
序列。 沒錯。
但是你宣布character
或者是一個選擇<wookieType>
或<starWarsEntity>
該錯誤表示character
元素不能包含name
元素,根據您的架構,這是正確的。
您在架構中聲明它的方式,您的文檔僅在您像這樣使用它時才會驗證:
<gallery>
<character >
<starWarsEntity>
<name>Luke Skywalker</name>
<species>Human</species>
<language>Basic</language>
<home>Tatooine</home>
</starWarsEntity>
</character>
<character >
<wookieType>
<name>Chewbacca</name>
<species>Wookie</species>
<language>Shyriiwook</language>
<home>Kashyyyk</home>
<battlecry>AARGH!</battlecry>
</wookieType>
</character>
</gallery>
您的驗證器發出一條錯誤消息,告訴您該文檔無效; 為什么你由此得出結論“兩個文件都是有效的?”?
您的架構表示“字符”元素可以有兩個子元素之一: starWarsEntity
或wookietype
。 如果您想讓您的 XML 對您的架構有效,您可以將 XML 更改為:
<gallery>
<character >
<starWarsEntity>
<name>Luke Skywalker</name>
...
</starWarsEntity>
</character>
<character >
<wookieType>
<name>Chewbacca</name>
...
<battlecry>AARGH!</battlecry>
</wookieType>
</character>
</gallery>
如果您想要一個接受 XML 原樣的模式,一種更簡單的方法是使用戰斗口號是可選的類型定義character
:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="character">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="species" type="xsd:string"/>
<xsd:element name="language" type="xsd:string"/>
<xsd:element name="home" type="xsd:string"/>
<xsd:element name="battlecry" type="xsd:string"
minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="character" type="character"/>
<xsd:complexType name="gallery">
<xsd:sequence>
<xsd:element ref="character" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="gallery" type="gallery"/>
</xsd:schema>
如果你想確保所有的 wookies,而且只有 wookies,有一個戰吼,最簡單的方法是在它們的元素名稱中區分 wookies 和其他角色。 讓我們假設wookie
元素描述 wookie 字符,而 'character' 元素描述非 wookie 字符。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="starWarsEntity">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="species" type="xsd:string"/>
<xsd:element name="language" type="xsd:string"/>
<xsd:element name="home" type="xsd:string"/>
<xsd:element name="battlecry" type="xsd:string"
minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="wookie-character">
<xsd:complexContent>
<xsd:restriction base="starWarsEntity">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="species" type="xsd:string">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="wookie">
<xsd:annotation>
<xsd:documentation>
For a wookie character, the species element conveys no new
information at all; we already know the character's species
from the name of the element. But we retain the species
element in order to keep 'wookie' and 'character' parallel
in structure.
</xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="language" type="xsd:string"/>
<xsd:element name="home" type="xsd:string"/>
<xsd:element name="battlecry" type="xsd:string"
minOccurs="1"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="non-wookie-character">
<xsd:complexContent>
<xsd:restriction base="starWarsEntity">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="species">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="()|[^w].*|.[^o].*|..[^o].*|...[^k}.*|....[^i].*|.....[^e].*">
<xsd:annotation>
<xsd:documentation>
For a non-wookie character, we allow any species except 'wookie'.
</xsd:documentation>
</xsd:annotation>
</xsd:pattern>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="language" type="xsd:string"/>
<xsd:element name="home" type="xsd:string"/>
<xsd:element name="battlecry" type="xsd:string"
maxOccurs="0"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="gallery">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="character" type="non-wookie-character"/>
<xsd:element name="wookie" type="wookie-character"/>
</xsd:choice>
</xsd:complexType>
<xsd:element name="gallery" type="gallery"/>
</xsd:schema>
XSD 的核心設計根據元素的名稱決定將哪種類型應用於元素,可能由其祖先的名稱和類型限定。 如果您將 XML 設計為使用這種方法而不是反對它,那么 XSD 將更易於使用。
在 XSD 1.1 中,可以使用斷言來確保每個帶有物種 = 'wookie' 的字符元素都有一個戰斗吶喊,或者檢查輸入中的其他類型的冗余。 但是斷言的可用性並不意味着突然違反 DRY 原則是個好主意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.