2012-09-19 99 views
1

我有一个架构如下:XML验证错误使用的XmlSchemaSet

<?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页。页面由帧列表组成。帧可以具有子帧或叶子(即不能包含子帧)。 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’可能元素的预期列表:‘页’”}

我认为它因为它是按顺序阅读的,而在我的情况下,这些元素可以以任何顺序出现。我尝试了xs:all属性,但它不能与maxoccurs = unbounded一起使用。任何其他方式?

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

这会是相同(1)?错误发生叶ID = 2

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

回答

1

您在Microsoft .NET上,这意味着您仅限于XSD 1.0可提供的功能。 xs:all compositor只支持maxOccurs="1"的粒子。这是你的第一个问题。

您的架构绝对不会捕获MetaData1MetaData2可能发生在任何地方的事实。 Leaf,FramePage根本没有这些元素。所以你必须为此做点什么。

无论如何,你都无法达到你想要的东西,如上所述;有些事情必须给予。您可以选择规定某些元素的位置,允许某些粒子之间存在某些变化,或者在“收集”项下“摆脱”您的重复元素。页面的页面,框架的框架,叶子的叶子。

另一个选择我会强烈考虑,鉴于您为元数据元素和版本提供的定义,以及哪些不会影响“等效”ADO.NET DataSet(假设它在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> 

以上的可视化:

QTAssistant showing XSD diagram

以及等效ADO。NET的DataSet(这个人是最容易使用的,以确认你的模型的描述):

QTAssistant showing XSD as ADO.NET DataSet

语义等价的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的:

Sample 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> 
+0

它仍然给出{“元素'框架'具有无效的子元素'叶'。列表中可能出现的元素:'Frame'。“}错误与您的模式有关。 请参阅我的原始XML,您缺少Leaf ID =”2“节点 –

+0

@FrankQ。,请参阅更新后的内容:应该是Frame或Leaf的无限选择我已经修复了 –

+0

谢谢你的工作!最后一件事,你如何强制Frame或Leaf必须包含Text值?如果我没有指定Text –