使用xsd验证Xml架构

时间:2013-08-09 09:43:04

标签: c# xml xsd xsd-validation

我正在尝试验证以下Xml。

string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
                    <ROOT xmlns:bk=""urn:samples"">
                        <RandomName1>
                            <Element1>v</Element1>
                            <Element2>v</Element2>
                            <Element3>v</Element3>
                            <Element4>v</Element4>
                    </RandomName1>
                        <RandomName2>
                            <Element1>v</Element1>
                            <Element2>v</Element2>
                            <Element3>v</Element3>
                            <Element4>v</Element4>
                    </RandomName2>
                    </ROOT>";

RandomNameN是任何字符串。我感兴趣的是确保Element1 - Element4存在且命名正确且架构匹配。

我试过以下

string xsdMarkup =
                @"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
                   <xsd:element name='ROOT'>
                    <xsd:complexType>
                     <xsd:sequence>
                      <xsd:any>
                        <xsd:complexType>
                            <xsd:sequence>
                                <xsd:element name ='Element1'/>
                                <xsd:element name ='Element2'/>
                                <xsd:element name ='Element3'/>
                                <xsd:element name ='Element4'/>
                            </xsd:sequence>
                        </xsd:complexType>
                        </xsd:any>
                     </xsd:sequence>
                    </xsd:complexType>
                   </xsd:element>
                  </xsd:schema>";

XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", XmlReader.Create(new StringReader(xsdMarkup)));

var xDoc = XDocument.Parse(xml);

bool errors = false;
string msg = string.Empty;

xDoc.Validate(schemas, (o, e) =>
    {
        msg = e.Message;
        errors = true;
    });

我正在System.Xml.Schema.XmlSchemaException

  

http://www.w3.org/2001/XMLSchema:complexType”元素不是   在这种情况下得到支持。

我还需要知道如何使RandomName1个节点不需要名称但是存在。我试图通过</xsd:any>代替</xsd:element>

来解决这个问题

2 个答案:

答案 0 :(得分:2)

正如我在my comment中提到的,<xsd:any>的使用不正确。

此外,<xsd:sequence>也不能包含complexType。请参阅: http://msdn.microsoft.com/en-us/library/ms256089.aspx

我还建议不要使用像RandomNameN这样的模式来识别你的元素,但更像是:<RandomName id='N'>。说到OO,您可以将XSD视为类定义,complexTypes是类,elementscomplexTypes类实例的引用,因此对于元素,您也应该定义他们的type

然后,您的XML文档将代表您的对象。其中Object的类型在Tag中表示。

您的complexType可以包含在元素内部。由于序列中包含可变数量的元素,因此应将maxOccurs设置为无界。生成的Schema应如下所示:

    <xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
       <xsd:element name='ROOT'>
          <xsd:complexType>
            <xsd:sequence>
               <xsd:element name="RandomName" maxOccurs='unbounded'>
                  <xsd:complexType>
                     <xsd:sequence>
                       <xsd:element name="Element" minOccurs='4' maxOccurs='4' type="xsd:string" />
                    </xsd:sequence>
                  </xsd:complexType>
               </xsd:element>
            </xsd:sequence>
          </xsd:complexType>
       </xsd:element>
    </xsd:schema>>

在这种情况下,您的XML可能如下所示:

<ROOT >
     <RandomName>
        <Element>v</Element>
        <Element>v</Element>
        <Element>v</Element>
        <Element>v</Element>
     </RandomName>
     <RandomName>
        <Element>v</Element>
        <Element>v</Element>
        <Element>v</Element>
        <Element>v</Element>
     </RandomName>
 </ROOT> 

最后,如果RandomName1 - RandonNameN来自同一类型(如果我们说的是OO,则为Class),那么XML文件中的标签也应该是相同的。 Element1-Element4也是如此。

但是,如果它们具有不同类型但具有共同元素,则可以使用继承。

Element1可能看起来像这样:

<complexType name="Element1">
    <complexContent>
        <extension base="Element">
            <sequence>
                <xs:element type="xs:string" name="additionalField"/>
            </sequence>
        </extension>
    </complexContent>
</complexType>

答案 1 :(得分:0)

我不知道xml生产者是否在你的控制之下。如果是,你可以解决它,例如使用具有固定名称的元素,其中某个属性包含随机名称,类似于<FixedNameElement randomName="...">