代码之家  ›  专栏  ›  技术社区  ›  Rookie Programmer Aravind

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

  •  8
  • Rookie Programmer Aravind  · 技术社区  · 14 年前

    对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 回复  |  直到 14 年前
        1
  •  4
  •   alk    13 年前

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

    <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可以很好地工作。

        2
  •  3
  •   Rookie Programmer Aravind    14 年前

    结论:

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

        3
  •  1
  •   W van Noort    14 年前

    也许可以使用名称空间:

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

    这可能会被证实。

        4
  •  1
  •   Andrej Adamenko    10 年前

    我也面临同样的问题。

    因为我从.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
  •  1
  •   Colin Smith    9 年前

    您可以使用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,我找不到任何免费的xml1.1处理器,但有几个付费选项是: