10

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

4

5 回答 5

5

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

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

于 2011-11-02T21:02:01.240 回答
3

结论:

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

于 2010-03-09T09:55:55.680 回答
2

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

于 2015-09-23T12:42:56.763 回答
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>

这可能会验证。

于 2010-03-08T16:32:56.370 回答
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当前线程才能正常工作。

于 2014-10-06T07:14:30.597 回答