【问题标题】:XML Schema: how to declare complexType that has either attribute or child with the same nameXML Schema:如何声明具有同名属性或子项的 complexType
【发布时间】:2013-02-09 09:04:40
【问题描述】:

对于我的 XSD 架构,我希望元素具有可以在元素的属性或其子元素中指定的必需附加值。

示例:应允许以下元素:

<flower color="red" />

或:

<flower><color>red</color></flower>

但以下元素不应该是有效的:

<flower />

和:

<flower></flower>

和:

<flower color="red"><color>blue</color></flower>

我完全不知道如何做到这一点。

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    在 XSD 1.0 中,您唯一的选择是以散文形式记录约束。 (例如,在模式的模式中所做的那样,它对元素声明有类似的约束。)

    在 XSD 1.1 中,您可以使用断言来记录和强制执行约束。稍微修改一下 Petru Gardea 建议的模式文档,我们有:

    <xs:schema targetNamespace="http://example.com/colors" 
           xmlns:tns="http://example.com/colors" 
           elementFormDefault="qualified" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
      <xs:simpleType name="flowerColor">
        <xs:restriction base="xs:normalizedString">
          <xs:minLength value="1"/>
        </xs:restriction>
      </xs:simpleType>
    
      <xs:complexType name="flowerVariantC">
        <xs:sequence>
          <xs:element name="color" 
                      type="tns:flowerColor" 
                      minOccurs="0"/>
        </xs:sequence>  
        <xs:attribute name="color" 
                      type="tns:flowerColor" 
                      use="optional"/>
        <xs:assert test="(./tns:color or ./@color)
            and not(./tns:color and ./@color)"/>
      </xs:complexType>
    
      <xs:element name="flower" type="tns:flowerVariantC"/>    
      <xs:element name="test"/>
    
    </xs:schema>
    

    鉴于刚刚显示的模式文档和以下实例,Saxon 拒绝第一和第四朵花元素为无效。

    <test xmlns="http://example.com/colors"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://example.com/colors colors.xsd">
      <flower/>
      <flower color="red"/>
      <flower><color>blue</color></flower>
      <flower color="blue"><color>blue</color></flower>
    </test>
    

    (也就是说,我的直觉是反对这种设计过于复杂:选择将颜色作为属性,或者选择将其作为子元素。每个都是合理的设计这一事实不是 意味着允许它在文档中变化是一个合理的设计。)

    【讨论】:

      【解决方案2】:

      假设 XSD 1.0,下面的示例是一个起点:

      <?xml version="1.0" encoding="utf-8" ?>
      <!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
      <xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <xsd:simpleType name="flowerColor">
              <xsd:restriction base="xsd:normalizedString">
                  <xsd:minLength value="1"/>
              </xsd:restriction>
          </xsd:simpleType>
      
          <xsd:complexType name="flowerVariantA">
              <xsd:attribute name="color" type="flowerColor" use="required"/>
          </xsd:complexType>
      
          <xsd:complexType name="flowerVariantB">
              <xsd:sequence>
                  <xsd:element name="color" type="flowerColor"/>
              </xsd:sequence>
          </xsd:complexType>
      
          <xsd:element name="flower" type="flowerVariantA"/>
      </xsd:schema>
      

      VariantA 和 B 是互斥的,并且匹配您的示例 XML 中的一个或另一个。如果您的意图是同时允许两者,那么 XSD 1.0 不允许“选择”将属性与元素混合的内容。

      此外,您无法控制 XML 元素的自动关闭;这意味着对于 VariantA,以下内容是有效的:

      <flower color="red"></flower>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多