1

我有一个架构如下:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="MyDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Leaf" />
  <xs:complexType name = "Leaf" mixed="true">
         <xs:attribute name="ID" type="xs:string" />
  </xs:complexType>

  <xs:element name="Frame" />
  <xs:complexType name="Frame" mixed="true">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Leaf" type ="Leaf" nillable="true"/>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Frame" type="Frame" nillable="true"/>
    </xs:sequence>
       <xs:attribute name="ID" type="xs:string" />
  </xs:complexType>

  <xs:element name="Document">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" name="Version" type="xs:string" />
        <xs:element minOccurs="0" maxOccurs="1" name="MetaData1" type="xs:string" />
        <xs:element minOccurs="0" maxOccurs="1" name="MetaData2" type="xs:string" />

        <xs:element minOccurs="1" maxOccurs="unbounded" name="Page" nillable="false">
          <xs:complexType mixed="true">
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" name="Frame" type="Frame" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

基本上它是一个递归结构。一个文档可以有一个页面列表。它必须包含至少 1 页。页面由框架列表组成。Frame 可以有子帧或叶子(即不能包含子帧)。MetaData1 和 MetaData2 是可选的,可以出现在任何地方。

示例 XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Document>
  <Version>1.1</Version>
  <MetaData1>Somemetadata</MetaData1>
  <Page>Page1
       <Frame ID="1">Frame1
          <Frame ID="2">SubFrame1
                <Frame ID="3">SubFrame2
                      <Leaf ID="1">Alone</Leaf>
                </Frame>
               <Leaf ID="2">Alone2</Leaf>
          </Frame>
        </Frame>
        <Frame ID="3">SubFrame3
        </Frame>
 </Page>
 <MetaData2 />
</Document>

我正在使用 XmlReaderSettings 和 XmlSchemaSet 对架构进行 XML 验证。出于某种原因,我收到以下 2 个错误:

1){“元素'文档'具有无效的子元素'Metadata2'。预期的可能元素列表:'Page'。”}

我认为这是因为它是按顺序阅读的,而在我的情况下,这些元素可以按任何顺序出现。我尝试使用 xs:all 属性,但它不适用于 maxoccurs=unbounded。还有什么办法吗?

2) {“元素‘框架’的子元素‘叶子’无效。预期的可能元素列表:‘框架’。”}

这可能与 (1) 相同吗?Leaf ID=2 发生错误

任何帮助,将不胜感激。谢谢

4

1 回答 1

1

您使用的是 Microsoft .NET,这意味着您受限于 XSD 1.0 所能提供的功能。xs:all合成器仅支持带有maxOccurs="1". 那是你的第一个问题。

您的架构绝对没有捕捉到MetaData1并且MetaData2可以在任何地方发生的事实。LeafFrame并且Page根本没有这些元素。所以你必须为此做点什么。

无论如何,如前所述,您无法完全实现您想要的;必须付出一些东西。您可以选择规定某些元素的位置,允许某些粒子之间的某些可变性,或者将您的重复元素“隐藏”在“集合”项下。页面为页面,框架为框架,叶子为叶子。

考虑到您为元数据元素和版本提供的定义,并且不会影响“等效”ADO.NET 数据集(假设在 XSD 1.0 中可能),我强烈考虑的另一个选择是使用属性。我将说明这种方法。如果您不确定其他选项,请告诉我,我将添加更多示例。

修改后的 XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="MyDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:complexType name = "Leaf" mixed="true">
        <xs:attribute name="ID" type="xs:string"/>
        <xs:attributeGroup ref="metadata"/>
    </xs:complexType>

    <xs:complexType name="Frame" mixed="true">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="Leaf" type ="Leaf" nillable="true"/>
            <xs:element name="Frame" type="Frame" nillable="true"/>
        </xs:choice>
        <xs:attribute name="ID" type="xs:string"/>
        <xs:attributeGroup ref="metadata"/>
    </xs:complexType>

    <xs:element name="Document">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="1" maxOccurs="unbounded" name="Page" nillable="false">
                    <xs:complexType mixed="true">
                        <xs:sequence>
                            <xs:element minOccurs="0" maxOccurs="unbounded" name="Frame" type="Frame"/>
                        </xs:sequence>
                        <xs:attributeGroup ref="metadata"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="version" type="xs:string" use="required"/>
            <xs:attributeGroup ref="metadata"/>
        </xs:complexType>
    </xs:element>

    <xs:attributeGroup name="metadata">
        <xs:attribute name="metadata1" type="xs:string"/>
        <xs:attribute name="metadata2" type="xs:string"/>
    </xs:attributeGroup>
</xs:schema>

上图的可视化:

QTAsistant 显示 XSD 图

和等效的 ADO.NET DataSet(这个最容易用来确认你对模型的描述):

QTAssistant 将 XSD 显示为 ADO.NET 数据集

可以验证上述内容的语义等效 XML(更改最少,很容易看到使用属性的影响):

<?xml version="1.0" encoding="UTF-8"?>
<Document version="1.1" metadata1="Somemetadata" metadata2="">
    <Page>Page1
        <Frame ID="1">Frame1
            <Frame ID="2">SubFrame1
                <Frame ID="3">SubFrame2
                    <Leaf ID="1">Alone</Leaf>
                </Frame>
            </Frame>
        </Frame>
        <Frame ID="3">SubFrame3
        </Frame>
    </Page>
</Document>

上述 XML 示意图:

示例 XML

显示有效实例的更复杂的示例 XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" version="version1" metadata1="metadata11" metadata2="metadata21">
    <Page metadata1="metadata11" metadata2="metadata21">text<Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
            <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
            <Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                <Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                    <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                </Frame>
                <Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                    <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                </Frame>
            </Frame>
            <Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                <Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                    <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                </Frame>
                <Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                    <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
                </Frame>
            </Frame>
        </Frame>
    </Page>
    <Page metadata1="metadata11" metadata2="metadata21">text<Frame ID="ID1" metadata1="metadata11" metadata2="metadata21">text<Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
            <Leaf ID="ID1" metadata1="metadata11" metadata2="metadata21">text</Leaf>
        </Frame>
    </Page>
</Document>
于 2012-09-19T05:03:14.533 回答