XSD 复杂元素中可以有多个指标吗?
Can you have more than one indicator in an XSD complex element?
我正在尝试构建一个新模式来验证 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 不允许您尝试执行的操作(将 <sequence/>
和 <all />
组合到一个复杂类型或元素中)。您也许可以使用嵌套内容模型实现类似的效果,但请注意您不能嵌套 <all>
,除非在另一个 <all />
下,否则您必须在另一个元素中定义它。但是,您可以将 <sequence>
或 <choice>
相互嵌套。
根据我对 XSD 的理解,您有 3 个可行的选择。
第一种是嵌套所有你想要在 <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>
还有第三个选项,有点像 'hack',但仍然允许指定元素无序,仍然是可选的,但仍然与其他强制的有序元素相邻出现。这嵌套了一个选择(maxOccurs="3")在序列下,父序列内部(序列>序列>选择):
<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>
然而,第三个选项有一个问题,<choice />
元素上的 maxOccurs="3"
呈现子元素上的 minOccurs
和 maxOccurs
(StockBrand
, TapeModel
和 TapeWidth
) 无意义;这意味着这些元素虽然仍然是可选的,但现在可以多次出现,只要元素的累计总数仍然是 3 或更少:
这变得有效(2 个相同元素 + 1 个以上):
<TapeWidth>1290</TapeWidth>
<TapeWidth>1291</TapeWidth>
<TapeModel>Hey</TapeModel>
这仍然有效(3 个相同):
<TapeWidth>1290</TapeWidth>
<TapeWidth>1291</TapeWidth>
<TapeWidth>1292</TapeWidth>
还有这个(1 个元素只出现 1 次):
<StockBrand>1290</StockBrand>
您可能会尝试通过摆弄顺序和选择嵌套的组合来找到另一个选项,但最佳做法是保持架构简单。就个人而言,我会推荐前两个选项而不是第三个选项,纯粹是为了让您的架构简单。
我正在尝试构建一个新模式来验证 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 不允许您尝试执行的操作(将 <sequence/>
和 <all />
组合到一个复杂类型或元素中)。您也许可以使用嵌套内容模型实现类似的效果,但请注意您不能嵌套 <all>
,除非在另一个 <all />
下,否则您必须在另一个元素中定义它。但是,您可以将 <sequence>
或 <choice>
相互嵌套。
根据我对 XSD 的理解,您有 3 个可行的选择。
第一种是嵌套所有你想要在 <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>
还有第三个选项,有点像 'hack',但仍然允许指定元素无序,仍然是可选的,但仍然与其他强制的有序元素相邻出现。这嵌套了一个选择(maxOccurs="3")在序列下,父序列内部(序列>序列>选择):
<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>
然而,第三个选项有一个问题,<choice />
元素上的 maxOccurs="3"
呈现子元素上的 minOccurs
和 maxOccurs
(StockBrand
, TapeModel
和 TapeWidth
) 无意义;这意味着这些元素虽然仍然是可选的,但现在可以多次出现,只要元素的累计总数仍然是 3 或更少:
这变得有效(2 个相同元素 + 1 个以上):
<TapeWidth>1290</TapeWidth>
<TapeWidth>1291</TapeWidth>
<TapeModel>Hey</TapeModel>
这仍然有效(3 个相同):
<TapeWidth>1290</TapeWidth>
<TapeWidth>1291</TapeWidth>
<TapeWidth>1292</TapeWidth>
还有这个(1 个元素只出现 1 次):
<StockBrand>1290</StockBrand>
您可能会尝试通过摆弄顺序和选择嵌套的组合来找到另一个选项,但最佳做法是保持架构简单。就个人而言,我会推荐前两个选项而不是第三个选项,纯粹是为了让您的架构简单。