【问题标题】:Validating XML instance with additional element使用附加元素验证 XML 实例
【发布时间】:2014-07-07 15:12:56
【问题描述】:

我正在使用 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>

添加了一个新标签&lt;newTag&gt;

更新:

这是用来验证 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;
    }
}

谢谢。

【问题讨论】:

    标签: xml .net-3.5 xsd


    【解决方案1】:

    它不会验证。

    您可以将&lt;xs:any&gt;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>
    

    如果要在三个已验证元素之后允许 许多 个未验证元素,则应在 &lt;xs:any&gt; 中使用 maxOccurs="unbounded"

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

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

    【讨论】:

    • 我按照建议修改了架构并通过了以下 XML 字符串,但验证失败:DSSDHSDEV5/19/2014 12:07:28 PM 10100数据>。似乎它采用了第一个“未声明的”元素 Ocr,但在 OcrNoBC 元素上失败了。如果我不知道会有多少“未声明”的元素,我该怎么做?
    • 您可以在这里测试 XSD 验证:utilities-online.info/xsdvalidation/#.U3ovJFhdVtM
    • 我明白了。你有 2 个额外的元素。该模式只允许一个。如果你想允许无限的额外非验证元素,那么你应该将maxOccurs="unbounded" 添加到&lt;xs:any&gt;
    • 您最后验证的示例是here
    • 似乎当我针对链接中的模式运行 XML 字符串时,只要它验证。但是,它在我的代码中失败了。我用我用来验证 XML 字符串的函数更新了原始帖子,但看不到它失败的原因。它返回:“找不到元素 'OcrNoBC' 的架构信息。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多