使用其他元素验证XML实例

时间:2014-05-19 15:20:48

标签: xml .net-3.5 xsd

我正在使用XML Schema文件来验证传递给Web服务的XML实例。我想知道是否有可能在XML实例中有一些可以忽略的标签,或者如果字符串与模式“完全”不匹配则会失败?

例如:

<?xml version="1.0" encoding="utf-8"?>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <xs:element name="DSSData">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="LTSN" type="xs:string" />
                <xs:element name="Timestamp" type="xs:string" />
                <xs:element name="Stats" maxOccurs="1" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Trp" type="xs:integer" nillable="true" minOccurs="1" />
                            <xs:element name="Keyed" type="xs:integer" nillable="true" minOccurs="1" />
                            <xs:element name="Pieces" type="xs:integer" nillable="true" minOccurs="1" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

我传递了以下XML字符串:

<DSSData><LTSN>abcd</LTSN><Timestamp></Timestamp><Stats><Trp>12</Trp><Keyed>34</Keyed><Pieces>12</Pieces><Ocr>45</Ocr><OcrNoBC>87</OcrNoBC></Stats></DSSData>

添加了新标记<newTag>

更新:

这是用于验证XML的内容:

bool bIsValid = ValidXMLDoc(my_xml_string, "", "some_schema.xsd");

public bool ValidXmlDoc(string xml, string sSchemaNamespace, string schemaUri)
{
    try
    {
        // Is the xml string valid?
        if(xml == null || xml.Length <  1)
        {
            return false;
        }
        StringReader srXml = new StringReader(xml);
        return ValidXmlDoc(srXml, sSchemaNamespace, schemaUri);
    }
    catch(Exception ex)
    {
        this.ValidationError = ex.Message;
        return false;
    }
}

public bool ValidXmlDoc(StringReader xml, string schemaNamespace, string schemaUri)
{
    // Continue?
    if(xml == null || schemaNamespace == null || schemaUri == null)
    {
        return false;
    }
    isValidXml = true;
    XmlValidatingReader vr;
    XmlTextReader tr;
    XmlSchemaCollection schemaCol = new XmlSchemaCollection();
    schemaCol.Add(schemaNamespace, schemaUri);
    try 
    { 
        // Read the xml.
        tr = new XmlTextReader(xml);

        // Create the validator.
        vr = new XmlValidatingReader(tr);

        // Set the validation tyep.
        vr.ValidationType = ValidationType.Schema;

        // Add the schema.
        if(schemaCol != null)
        {
            vr.Schemas.Add(schemaCol);
        }
        // Set the validation event handler.
        vr.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

        // Read the xml schema.
        while(vr.Read()) 
        { 
        } 
        vr.Close(); 
        return isValidXml;
    } 
    catch(Exception ex) 
    { 
        this.ValidationError = ex.Message;
        return false; 
    } 
    finally
    {
        // Clean up...
        vr = null;
        tr = null;
    }
}

感谢。

1 个答案:

答案 0 :(得分:0)

它不会验证。

您可以将<xs:any>processContents="skip""lax"一起用作已验证序列中任何未经验证的标记的占位符。

例如,如果要在序列末尾允许可选的任意未经验证的标记,可以使用:

<xs:sequence>
    <xs:element name="Trp" type="xs:integer" nillable="true" minOccurs="1" />
    <xs:element name="Keyed" type="xs:integer" nillable="true" minOccurs="1" />
    <xs:element name="Pieces" type="xs:integer" nillable="true" minOccurs="1" />
    <xs:any processContents="lax" minOccurs="0"/>
</xs:sequence>

将验证您的实例:

<DSSData>
    <LTSN>abcd</LTSN>
    <Timestamp/>
    <Stats>
        <Trp>12</Trp>
        <Keyed>34</Keyed>
        <Pieces>12</Pieces>
        <newTag>45</newTag>
    </Stats>
</DSSData>

如果您想在三个经过验证的元素之后允许许多未经验证的元素,则应使用maxOccurs="unbounded"中的<xs:any>

<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>

您可以在此fiddle中测试验证。