【问题标题】:Creating an XML Schema with attributes and elements contingent on other attributes使用取决于其他属性的属性和元素创建 XML 模式
【发布时间】:2009-10-21 23:32:29
【问题描述】:

我正在尝试开发一种模式,该模式将验证我继承的一些现有 XML 文件。我希望架构尽可能多地完成验证工作。挑战在于属性和元素取决于其他属性的值。

真实数据非常抽象,所以我创建了一些简单的示例。假设我有以下 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Creature type="human" nationality="British">
    <Address>London</Address>
</Creature>

<?xml version="1.0" encoding="UTF-8"?>
<Creature type="animal" species="Tiger">
    <Habitat>Jungle</Habitat>
</Creature>

如果生物的“类型”是“人类”,我将有一个“国籍”属性和一个“地址”子元素。如果生物的“类型”是“动物”,我将有一个“物种”属性和一个“栖息地”子元素。就本示例而言,具有“物种”或“栖息地”的“人类”是无效的,具有“国籍”或“地址”的“动物”也是如此。

如果“Creature”不是根元素,我可能在根元素下方有两个不同的“Creature”选择,但是当“Creature”是根元素时,我不知道如何使这项工作发挥作用。

是否可以为这些文件创建仅匹配有效文档的架构?如果是这样,我会怎么做?

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    您可以为此目的使用 xsi:type 属性(您必须使用 XMLSchema-instance 命名空间中的 xsi:type 而不是您自己的命名空间,否则它将不起作用)。

    在架构中,您声明一个声明为抽象的基类型,并为每个子类型创建额外的复杂类型(具有特定于该类型的元素/属性)。

    请注意,虽然此解决方案有效,但最好为每种类型使用不同的元素名称(xsi:type 有点违背规范,因为它现在是 type 属性与定义的元素名称相结合类型,而不仅仅是元素名称)。

    例如:

    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
    <xs:element name="Creature" type="CreatureType">
    </xs:element>
    
      <xs:complexType name="CreatureType" abstract="true">
        <!-- any common validation goes here -->
      </xs:complexType>
    
      <xs:complexType name="Human">
        <xs:complexContent>
          <xs:extension base="CreatureType">
            <xs:sequence maxOccurs="1">
              <xs:element name="Address"/>
            </xs:sequence>
            <xs:attribute name="nationality" type="xs:string"/>
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>
    
      <xs:complexType name="Animal">
        <xs:complexContent>
          <xs:extension base="CreatureType">
            <xs:sequence maxOccurs="1">
              <xs:element name="Habitat"/>
            </xs:sequence>
            <xs:attribute name="species" type="xs:string"/>
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>
    
    </xs:schema>
    

    此架构将验证这两个:

    <?xml version="1.0" encoding="UTF-8"?>
    <Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:type="Human" 
              nationality="British">
        <Address>London</Address>
    </Creature>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:type="Animal" 
              species="Tiger">
        <Habitat>Jungle</Habitat>
    </Creature>
    

    但不是这个:

    <?xml version="1.0" encoding="UTF-8"?>
    <Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:type="SomeUnknownThing" 
              something="something">
        <Something>Something</Something>
    </Creature>
    

    或者这个:

    <?xml version="1.0" encoding="UTF-8"?>
    <Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:type="Human" 
              species="Tiger">
        <Habitat>Jungle</Habitat>
    </Creature>
    

    【讨论】:

    • 感谢您在解决方案中提供非常准确的答案和出色的示例。您刚刚节省了我数小时的互联网搜索时间
    • 很好的例子!您能否解释一下为什么 xsi:type 有效而 type 不在 XML 文件中?
    • 优秀的范例!但在我的 XML 游戏级别规范中,I 想要指定规范,而不是 XML Schema(我更喜欢“type”而不是“xsi:type”)。那么,这是 XML Schema 的弱点吗?
    猜你喜欢
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多