【问题标题】:If defined in XSD, then validate, otherwise - allow, but do not validate如果在 XSD 中定义,则验证,否则 - 允许,但不验证
【发布时间】:2019-03-13 00:00:13
【问题描述】:

一个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 元素是强制性的,具有严格的结构。
  • 不需要任何其他元素,结构松散。
  • firstItemStoragesecondItemStorage 之类的元素在XSD 模式中定义并出现在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 中定义的元素时,我会生成错误。

如何安全地定义我想要的?

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    在 XSD 1.1 中,您不会在特定元素粒子和通配符粒子之间产生任何歧义;特定粒子具有更高的优先级。如果您迁移到 XSD 1.1(这意味着使用非 Microsoft 工具),您会发现满足您的要求要容易得多。

    如果您准备将元数据元素限制在第一位,那么您可以使用 (metadata, xs:any*) 的内容模型执行此操作(即使在 XSD 1.0 中),其中xs:any 具有 processContents= “松懈”。宽松的验证基本上意味着如果有一个全局元素声明,然后验证它,否则,不验证。然后,您的 firstItemStoragesecondItemStorage 元素声明必须成为全局元素声明(xs:element 作为 xs:schema 的子元素)。

    迁移到 XSD 1.1 使您可以解除元数据必须先出现的限制(我不确定您是否想将其限制为仅出现一次)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-25
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 2014-02-25
      相关资源
      最近更新 更多