在一个XSD复杂元素中可以有多个指标吗?

问题描述 投票:0回答:1

我正试图建立一个新的模式,以便为我的工作验证XML。但我很难回答这个问题:我能否以及如何创建一个复杂元素,它有一些元素需要在一个设定的序列中,而其他子元素则不需要?最终我认为我应该能够在两组元素周围有开闭 "sequence "标签和开闭 "all "标签,但xsd似乎不喜欢这样。我的情况是这样的。

<xsd:complexType name="Original">
        <xsd:sequence>
            <xsd:element maxOccurs="1" minOccurs="1" name="AssetIdentifier" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>Definition: The Asset Identifier element is intended to
                        reflect the root of all following digital filenames.</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element maxOccurs="1" minOccurs="0" name="ArchiveID" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>Definition: The Filename element in this section is
                        intended to reflect the root of all the following derivative digital
                        filenames.</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element maxOccurs="1" minOccurs="1" name="Title" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>Definition: The known title of the asset. If no title is
                        known, one can be assigned; a number or letter sequence, whichever is
                        the most logical. Using the value "unknown" is also
                        acceptable.</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element maxOccurs="1" minOccurs="1" name="RecordDate" type="xsd:date">
                <xsd:annotation>
                    <xsd:documentation>Definition: The actual recording date of the asset.
                        Estimates, partial dates, and date ranges (i.e. 19XX, Feb. 19-24,
                        1934-1935, etc.) are allowable, as is 'unknown'. Best practice, when
                        applicable, is to use the YYYY-MM-DD format in accordance with ISO 8601.
                        Even partial dates, i.e. 1990-05 should adhere to this
                        format.</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element maxOccurs="1" minOccurs="1" name="FormatType" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>Definition: The format of the analog asset, i.e. Open
                        Reel, Grooved Disc, DAT, Cassette, VHS, 16mm film, EIAJ,
                        etc.</xsd:documentation>
                    <xsd:documentation>Best Practice: The MediaPreserve maintains a list of
                        controlled vocabularies organized by media type at: www.dontknowyet.com.
                        However, MP opted to meake this an unrestricted element in the event
                        that other ogranizations have their own controlled vocabularies in
                        place.</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
         </xsd:sequence>
        <xsd:all>
            <xsd:element maxOccurs="1" minOccurs="0" name="StockBrand" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>If known definitively</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element maxOccurs="1" minOccurs="0" name="TapeModel" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>If applicable. Usually applies to DAT tapes, open reels,
                        and wire recordings.</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element maxOccurs="1" minOccurs="0" name="TapeWidth" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>Typically only applicable for open reel
                        audio</xsd:documentation>
                </xsd:annotation>
            </xsd:element>
        </xsd:all>

xsd xsd-validation validationrules
1个回答
0
投票

不幸的是,XSDs不允许你试图做的事情(结合 <sequence/><all /> 内的单一复杂类型或元素)。) 你也许可以用一个嵌套的内容模型来实现类似的东西,但注意你不能嵌套 <all> 除另 <all />否则你必须在另一个元素中定义它。但是,你可以将以下两种元素嵌套 <sequence><choice> 彼此之下。

根据我对XSD的理解,你有三个可行的选择。

第一种是将所有你想要的元素嵌套在 <all /> 来包含在自己的子元素中。

<xs:complexType name="Original">
  <xs:sequence>
    <!-- AssetIdentifier to FormatType left out for brevity -->
    <xs:element name="Misc">
      <xs:complexType>
        <xs:all>
          <xs:element maxOccurs="1" minOccurs="0" name="StockBrand" type="xs:string" />
          <xs:element maxOccurs="1" minOccurs="0" name="TapeModel" type="xs:string" />
          <xs:element maxOccurs="1" minOccurs="0" name="TapeWidth" type="xs:string" />
        </xs:all>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>
<!-- For the above, valid XML would be: -->
<Original>
  <AssetIdentifier>AssetIdentifier0</AssetIdentifier>
  <Title>Title0</Title>
  <RecordDate>2006-05-04</RecordDate>
  <FormatType>FormatType0</FormatType>
  <Misc>
    <!-- Optional & order doesn't matter -->
    <StockBrand>what</StockBrand>
    <TapeWidth>1290</TapeWidth>
    <TapeModel>Hey</TapeModel>
  </Misc>
</Original>

二是将这些元素嵌套在另一个子元素之下 <sequence />它允许你放弃指定另一个子元素,但现在要求元素按照模式中指定的顺序出现。请注意,嵌套序列本身可以是可选的。

<xs:complexType name="Original">
  <xs:sequence>
    <!-- AssetIdentifier to FormatType left out for brevity -->
    <xs:sequence minOccurs="0">
      <xs:element maxOccurs="1" minOccurs="0" name="StockBrand" type="xs:string" />
      <xs:element maxOccurs="1" minOccurs="0" name="TapeModel" type="xs:string" />
      <xs:element maxOccurs="1" minOccurs="0" name="TapeWidth" type="xs:string" />
    </xs:sequence>
  </xs:sequence>
</xs:complexType>

<!-- For the above, valid XML would be: -->
<Original>
  <AssetIdentifier>AssetIdentifier0</AssetIdentifier>
  <Title>Title0</Title>
  <RecordDate>2006-05-04</RecordDate>
  <FormatType>FormatType0</FormatType>
  <!-- Optional below, but must be ordered -->
  <StockBrand>what</StockBrand>
  <TapeModel>Hey</TapeModel>
  <TapeWidth>1290</TapeWidth>
</Original>

还有第三个选项是一个有点 "黑客 "的选项,但仍然允许指定元素不排序,仍然是可选的,但仍然出现在其他强制性的,按顺序排列的元素旁边。这就把一个选择(用 maxOccurs="3")下的序列,在父序列(sequence > sequence > choice)内。

<xs:complexType name="Original">
  <xs:sequence>
    <!-- AssetIdentifier to FormatType left out for brevity -->
    <xs:sequence>
      <xs:choice maxOccurs="3" minOccurs="0">
        <xs:element name="StockBrand" type="xs:string"/>
        <xs:element name="TapeModel" type="xs:string"/>
        <xs:element name="TapeWidth" type="xs:string"/>
      </xs:choice>
    </xs:sequence>
  </xs:sequence>
</xs:complexType>
<!-- For the above, valid XML would be: -->
<Original>
  <AssetIdentifier>AssetIdentifier0</AssetIdentifier>
  <Title>Title0</Title>
  <RecordDate>2006-05-04</RecordDate>
  <FormatType>FormatType0</FormatType>
  <!-- Optional, unordered, but there's a catch: -->
  <TapeWidth>1290</TapeWidth>
  <StockBrand>what</StockBrand>
  <TapeModel>Hey</TapeModel>
</Original>

然而,第3个选项有一个问题,即 maxOccurs="3" 在...上 <choice /> 元素渲染了 minOccursmaxOccurs 的子元素上 (StockBrand, TapeModelTapeWidth)没有意义;这意味着这些元素虽然仍然是可选的,但现在可以出现一次以上,只要元素的累计总数仍然是3或更少。

这将成为有效的(2个相同的元素+1个更多的元素)。

  <TapeWidth>1290</TapeWidth>
  <TapeWidth>1291</TapeWidth>
  <TapeModel>Hey</TapeModel>

而这个仍然有效(3个相同的)。

  <TapeWidth>1290</TapeWidth>
  <TapeWidth>1291</TapeWidth>
  <TapeWidth>1292</TapeWidth>

还有这个(只是1个元素的出现)。

  <StockBrand>1290</StockBrand>

你也许可以尝试通过序列和选择嵌套的组合来找到另一个选项,但最好的做法是保持你的模式简单。我个人推荐前两个选项,而不是第三个,纯粹是为了保持你的模式简单。

© www.soinside.com 2019 - 2024. All rights reserved.