簡體   English   中英

XSD 不同類型同名

[英]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>

您的驗證器發出一條錯誤消息,告訴您該文檔無效; 為什么你由此得出結論“兩個文件都是有效的?”?

您的架構表示“字符”元素可以有兩個子元素之一: starWarsEntitywookietype 如果您想讓您的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM