【问题标题】:XML Schema Children With the Same Element具有相同元素的 XML 模式子项
【发布时间】:2013-12-13 17:26:14
【问题描述】:

我正在尝试为接受图像的服务器编写 XML 模式。图像要么都带有遮罩,要么都没有遮罩。

我想生成这样的 XML:

<?xml version="1.0" encoding="utf-8"?>
<FIVR>
  <meal>
    <media>
      <image2D filename="filename1">
        <mask filename="filename1" />
      </image2D>
      <image2D filename="filename2">
        <mask filename="filename1" />
      </image2D>
      <image2D filename="filename3">
          <mask filename="filename1" />
      </image2D>
      <image2D filename="filename4">
          <mask filename="filename1" />
      </image2D>
      <image2D filename="filename5">
         <mask filename="filename1" />
      </image2D>
    </media>
  </meal>
</FIVR>

<?xml version="1.0" encoding="utf-8"?>
<FIVR>
  <meal>
    <media>
      <image2D filename="filename1">
      </image2D>
      <image2D filename="filename2">
      </image2D>
      <image2D filename="filename3">
      </image2D>
      <image2D filename="filename4">
      </image2D>
      <image2D filename="filename5">
      </image2D>
    </media>
  </meal>
</FIVR>

但是,如果某些 image2D 元素具有掩码子元素而其他元素没有,则验证应该会失败。例如,应拒绝以下内容:

<?xml version="1.0" encoding="utf-8"?>
<FIVR>
  <meal>
    <media>
      <image2D filename="filename1">
      </image2D>
      <image2D filename="filename2">
        <mask filename="filename1" />
      </image2D>
      <image2D filename="filename3">
          <mask filename="filename1" />
      </image2D>
      <image2D filename="filename4">
      </image2D>
      <image2D filename="filename5">
      </image2D>
    </media>
  </meal>
</FIVR>

我可以使用 XSD 架构来表达吗?

我现在的架构是这样的:

<xs:element name="FIVR">
<xs:complexType>
  <xs:sequence>
    <xs:element name="meal" minOccurs="1" maxOccurs="1">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="media" minOccurs="1" maxOccurs="1">
            <xs:complexType>
              <xs:choice>
                <xs:element name="image2D" minOccurs="5" maxOccurs="5" >
                  <xs:complexType>
                    <xs:all minOccurs="0">
                      <xs:element name="mask">
                        <xs:complexType>
                          <xs:attribute name="filename" type="xs:string" use="required"/>
                        </xs:complexType>
                      </xs:element>
                    </xs:all>
                    <xs:attribute name="filename" type="xs:string" use="required"/>
                  </xs:complexType>
                </xs:element>
              </xs:choice>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

【问题讨论】:

    标签: xml xsd schema


    【解决方案1】:

    一个简单的解决方案是将媒体声明为采用一系列无掩码图像或一组带有掩码的图像。由于这两种图像具有不同的验证行为,因此最简单的方法是给它们起不同的名称。然后内容模型就变成了

    <xs:choice>
      <xs:element ref="image2D-mask" maxOccurs="unbounded"/>
      <xs:element ref="image2D-nomask" maxOccurs="unbounded"/>
    </xs:choice>
    

    你的困难的根源是希望为两个不同的事物使用同一个名字。

    【讨论】:

    • 我更喜欢这种方法,而不是我的 Schema 1.1 xs:assert 答案,如果 OP 可以以这种方式重新设计。 +1
    【解决方案2】:

    如果您使用的是 XML Schema 1.1,您可以像这样使用 xs:assert 通过 XPath 2.0 specify co-occurrence constraints(未经测试):

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               targetNamespace="my/sample/namespace"
               xmlns="my/sample/namespace"
               elementFormDefault="qualified">
      <xs:element name="FIVR">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="meal" minOccurs="1" maxOccurs="1">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="media" minOccurs="1" maxOccurs="1">
                    <xs:complexType>
                      <xs:choice>
                        <xs:element name="image2D" minOccurs="5" maxOccurs="5" >
                          <xs:complexType>
                            <xs:all minOccurs="0">
                              <xs:element name="mask">
                                <xs:complexType>
                                  <xs:attribute name="filename" type="xs:string" use="required"/>
                                </xs:complexType>
                              </xs:element>
                            </xs:all>
                            <xs:attribute name="filename" type="xs:string" use="required"/>
                          </xs:complexType>
                        </xs:element>
                      </xs:choice>
                      <xs:assert test="(count(image2D/mask) = 0) or (count(image2D/mask) = count(image2D))"/>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    如果您使用的是 XML Schema 1.0,则无法在架构中表达这样的约束,但可以使用 Schematron 或在应用程序级别进行检查。

    【讨论】:

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