如何忽略未知标签的验证?

时间:2010-03-08 15:38:42

标签: xml xsd xsd-validation

XSD功能的另一个挑战,
我一直在发送我的客户端的XML文件,这些文件将包含0个或更多未定义或[调用]意外标记(可能出现在层次结构中)。好吧,它们对我来说是多余的标签..所以我必须忽略它们的存在,但是除此之外还有一些需要验证的标签。

这是一个示例XML:

<root>
  <undefined_1>one</undefined_1>
  <undefined_2>two</undefined_2>
  <node>to_be_validated</node>
  <undefined_3>two</undefined_3>
  <undefined_4>two</undefined_4>
</root>

我试过的XSD:

  <xs:element name="root" type="root"></xs:element>
  <xs:complexType name="root">
    <xs:sequence>
      <xs:any maxOccurs="2" minOccurs="0"/>
      <xs:element name="node" type="xs:string"/>
      <xs:any maxOccurs="2" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType
由于某些原因,XSD不允许这样做 上面提到的例子只是一个例子。实用的XML带有XML标签的复杂层次结构。

如果你能破解它,请告诉我。

顺便说一句,替代解决方案是在验证过程之前插入XSL转换。好吧,我正在避免它,因为我需要更改触发验证过程的.Net代码,至少我的公司支持。

5 个答案:

答案 0 :(得分:4)

如果您尚未完成此操作,可以尝试以下操作:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root" type="root"></xs:element>
  <xs:complexType name="root">
    <xs:sequence>
      <xs:any maxOccurs="2" minOccurs="0" processContents="skip"/>
      <xs:element name="node" type="xs:string"/>
      <xs:any maxOccurs="2" minOccurs="0" processContents="skip"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

在Linux下,使用libxml版本20706可以正常使用xmllint。

答案 1 :(得分:3)

结论:

XSD无法做到这一点。我试图达到要求的所有方法都被验证工具命名为“含糊不清”,伴随着一堆错误。

答案 2 :(得分:1)

也许它可以使用命名空间:

<xs:element name="root" type="root"></xs:element> 
  <xs:complexType name="root"> 
    <xs:sequence> 
      <xs:any maxOccurs="2" minOccurs="0" namespace="http://ns1.com" /> 
      <xs:element name="node" type="xs:string"/> 
      <xs:any maxOccurs="2" minOccurs="0" namespace="http://ns2.com"/> 
    </xs:sequence> 
  </xs:complexType>

这可能会验证。

答案 3 :(得分:1)

我遇到了同样的问题。

因为我从.NET调用了验证;我决定取消ValidationEventHandler中的特定验证错误作为解决方法。它对我有用。

    private void ValidationEventHandler(object sender, ValidationEventArgs e)
    {
        switch (e.Severity)
        {
            case XmlSeverityType.Warning:
                // Processing warnings
                break;
            case XmlSeverityType.Error:
                if (IgnoreUnknownTags
                    && e.Exception is XmlSchemaValidationException
                    && new Regex(
                        @"The element '.*' has invalid child element '.*'\."
                        + @" List of possible elements expected:'.*'\.")
                       .IsMatch(e.Exception.Message))
                {
                    return;
                }
                // Processing errors
                break;
            default:
                throw new InvalidEnumArgumentException("Severity should be one of the valid values");
        }
    }

必须将Thread.CurrentUICulture设置为英语或CultureInfo.InvariantCulture以使当前线程正常工作。

答案 4 :(得分:1)

您可以在XML 1.1中使用名为&#34; Open Content&#34;的新功能。简而言之,允许您指定其他&#34;未知&#34;元素可以添加到不同位置的复杂类型中,以及解析器在遇到任何元素时应该做什么

使用XML 1.1,您的复杂类型将变为:

<xs:element name="root" type="root" />
<xs:complexType name="root"> 
  <xs:openContent mode="interleave">
    <xs:any namespace="##any" processContents="skip"/>
  </xs:openContent>

  <xs:sequence> 
    <xs:element name="node" type="xs:string"/> 
  </xs:sequence> 
</xs:complexType>

如果你有很多复杂的类型,你也可以设置一个&#34;默认&#34;在架构顶部打开内容模式:

<xs:schema ...>
  <xs:defaultOpenContent mode="interleave">
    <xs:any namespace="##any" processContents="skip"/>
  </xs:defaultOpenContent>

  ...
</xs:schema>

开放内容的W3C规范可以在http://www.w3.org/TR/xmlschema11-1/#oc找到,并且在http://www.ibm.com/developerworks/library/x-xml11pt3/#N102BA处有一个很好的写法。

不幸的是,.NET不支持XML 1.1,但我无法找到任何免费的XML 1.1处理器 - 但是有几个付费选项: