xml - 如果在 XSD 中定义,则验证,否则 - 允许,但不验证
问题描述
一个 XML 文档如下:
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://localhost/app/myschema.xsd myschema.xsd">
<metadata>
<source appVer="2.10.0.3" structure="2.10.18.34" sequence="00000001" dt="2014-08-26T11:13:15"/>
</metadata>
<firstItemStorage>
<row col1="..." col2="..." />
<row col1="..." col2="..." />
<row col1="..." col2="..." />
</firstItemStorage>
<secondItemStorage>
<row col1="..." col2="..." />
<row col1="..." col2="..." />
<row col1="..." col2="..." />
</secondItemStorage>
<anyOtherElement>
<!-- Any XML -->
</anyOtherElement>
</data>
我想定义以下内容:
- 文档的根元素必须是
data
. - 在它里面可以有任何顺序的任何元素。
metadata
元素是强制性的并且具有严格的结构。- 不需要任何其他元素,并且结构松散。
- 当 XSD 模式中定义了类似
firstItemStorage
和的元素secondItemStorage
并出现在 XML 文档中时,应验证它们是否具有零个或无限个row
元素,这些元素具有零个或无限个属性,以任何顺序排列。定义的属性被验证,未定义的被禁止。 - 当 XML 文档中出现未在 XSD 模式中定义的任何其他元素时,不会发生验证错误,并且不会验证它们的内容。
我的架构如下:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="metadata" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="source">
<xs:complexType>
<xs:attribute name="appVer" type="xs:string" use="required"/>
<xs:attribute name="structure" type="xs:string" use="required"/>
<xs:attribute name="sequence" type="xs:unsignedInt" use="required"/>
<xs:attribute name="dt" type="xs:dateTime" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="firstItemStorage" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="row" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<!-- Attributes could have any order -->
<xs:attribute name="id" type="xs:int" />
<xs:attribute name="sid" type="xs:int" />
<xs:attribute name="id_group" type="xs:int" />
<xs:attribute name="consum" type="xs:double" />
<xs:attribute name="overloadlimit" type="xs:double" />
<xs:attribute name="upd" type="xs:dateTime" />
<!-- Any other attributes are prohibited -->
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="secondItemStorage" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="row" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<!-- Attributes could have any order -->
<xs:attribute name="id" type="xs:int" />
<xs:attribute name="meaning" type="xs:string" />
<xs:attribute name="visible" type="xs:boolean" />
<xs:attribute name="a_counter" type="xs:boolean" />
<xs:attribute name="activities" type="xs:boolean" />
<xs:attribute name="upd" type="xs:dateTime" />
<!-- Any other attributes are prohibited -->
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- Any other elements are allowed, but not validated -->
<xs:any />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
xs:any
我对元素有问题:
any
元素不仅允许任何未知元素,还允许已知元素的任何属性- 我收到来自 Visual Studio 的警告:
警告 26 通配符“##any”允许元素“操作”,并导致内容模型变得不明确。必须形成一个内容模型,使得在元素信息项序列的验证过程中,直接、间接或隐含地包含在其中的粒子,用于依次验证序列中的每个项目,可以唯一确定,而无需检查其内容或属性。该项目,并且没有关于序列其余部分中的项目的任何信息。
如果没有any
元素,当 XML 文档中出现 XSD 中未定义的元素时,我会生成错误。
如何安全地定义我想要的?
解决方案
在 XSD 1.1 中,您不会在特定元素粒子和通配符粒子之间产生任何歧义。特定粒子具有更高的优先级。如果您迁移到 XSD 1.1(这意味着使用非 Microsoft 工具),您会发现更容易满足您的要求。
如果您准备将元数据元素限制在第一位,那么您可以使用 (metadata, xs:any*) 的内容模型执行此操作(即使在 XSD 1.0 中),其中xs:any
具有 processContents="lax"。宽松的验证基本上意味着如果有一个全局元素声明,然后验证它,否则,不验证。然后,您的firstItemStorage
和secondItemStorage
元素声明必须成为全局元素声明(xs:element
作为 的子元素xs:schema
)。
迁移到 XSD 1.1 使您能够解除元数据必须首先出现的限制(我不确定您是否想将其限制为仅出现一次)。
推荐阅读
- javascript - 检查给定数字是否是另一个小数的倍数
- sql - 跨数据库表减去常量
- sql - 如何使用 Big Query SQL Standard 将日期 YYYY-MM-DD 转换为字符串 YYYYMM?
- docker - 使用奇异性在snakemake中规则:未终止的带引号的字符串
- angular - 如何将 Aria 标签应用于 PrimeNG 组件的子元素?
- sql - 如何选择 MS ACCESS OLE 对象只有数据?
- pyarrow - 如何为 pyarrow 设置 libhdfs.so 的路径?
- python - 从单独的脚本运行 Scrapy -o JSON
- python-3.x - 在python中选择没有if语句的函数
- javascript - 将Mongodb数据存储到sails js中的变量中?