【问题标题】:How to ignore the validation of Unknown tags?如何忽略未知标签的验证?
【发布时间】:2011-01-25 00:55:13
【问题描述】:

对 XSD 功能的另一个挑战,

我的客户一直在发送 XML 文件,这些文件将有 0 个或多个未定义或 [call] 意外标签(可能出现在层次结构中)。好吧,它们对我来说是多余的标签..所以我不得不忽略它们的存在,但除了它们之外,还有一些需要验证的标签。

这是一个示例 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 代码,这至少得到我公司的支持。

【问题讨论】:

  • 是不是没有针对 schema 进行验证的问题?
  • 是的 .. 我想表明“我不知道怎么做 .. 我试过了” ..

标签: xml xsd xsd-validation


【解决方案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>

这可能会验证。

【讨论】:

  • 深思熟虑 [+1].. 但不幸的是在我的情况下不起作用。感谢您的回复。 :-)
【解决方案2】:

结论:

这在 XSD 中是不可能的。我试图达到要求的所有方法都被验证工具命名为“模棱两可”,伴随着一堆错误。

【讨论】:

    【解决方案3】:

    如果您还没有这样做,您可以尝试以下方法:

    <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 可以正常工作。

    【讨论】:

    • 但是它仍然不允许第一个元素是 ANY! :(
    • 请问到底是什么问题?
    • 这是我得到的错误:通配符“##any”允许元素“节点”,并导致内容模型变得不明确。某某
    • 这看起来像是一个概念问题。有关详细信息,请参阅此处:w3.org/TR/xmlschema-1/#cos-nonambig 对我来说一个有趣的事实是,显然不同的工具处理这种情况的方式不同。正如我所写,我提供的解决方案确实适用于提到的工具。
    • 好吧。感谢您提供的信息和您宝贵的时间 :) 虽然我无法实现它,但它很有帮助,因为我只需要处理 .net :)
    【解决方案4】:

    我遇到了同样的问题。

    因为我从 .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 以使当前线程正常工作,这一点很重要。

    【讨论】:

      【解决方案5】:

      您可以利用 XML 1.1 中称为“开放内容”的新功能。简而言之,它允许您指定额外的“未知”元素可以添加到复杂类型的不同位置,以及解析器遇到这些元素时应该做什么。

      使用 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>
      

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

      <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 处理器 - 但有几个付费选项是:

      【讨论】:

        猜你喜欢
        • 2016-11-12
        • 2018-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-08
        • 2013-02-18
        • 1970-01-01
        • 2012-08-30
        相关资源
        最近更新 更多