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

发布于 2024-08-25 01:23:49 字数 988 浏览 5 评论 0原文

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

One more challenge to the XSD capability,

I have been sending XML files by my clients, which will be having 0 or more undefined or [call] unexpected tags (May appear in hierarchy). Well they are redundant tags for me .. so I have got to ignore their presence, but along with them there are some set of tags which are required to be validated.

This is a sample 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>

And the XSD I tried with:

  <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 doesn't allow this, due to certain reasons.
The above mentioned example is just a sample. The practical XML comes with the complex hierarchy of XML tags ..

Kindly let me know if you can get a hack of it.

By the way, The alternative solution is to insert XSL-transformation, before validation process. Well, I am avoiding it because I need to change the .Net code which triggers validation process, which is supported at the least by my company.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

乙白 2024-09-01 01:23:49

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

<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 配合使用。

In case your not already done with this, you might try the following:

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

Under Linux this works fine with xmllint using libxml version 20706.

梓梦 2024-09-01 01:23:49

结论:

这对于 XSD 来说是不可能的。我试图实现该要求的所有方法都被验证工具命名为“不明确”,并伴随着一堆错误。

Conclusion:

This is not possible with XSD. All the approaches I was trying to achieve the requirement were named as "ambiguous" by validation-tools, accompanying bunch of errors.

似狗非友 2024-09-01 01:23:49

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

You could make use of a new feature in XML 1.1 called "Open Content". In short, it allows you to specify that additional "unknown" elements can be added to a complex type in various positions, and what the parser should do if it hit any of those elements.

Using XML 1.1, your complex type would become:

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

If you have a lot of complex types, you can also set a "default" open content mode at the top of your schema:

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

  ...
</xs:schema>

The W3C spec for Open Content can be found at http://www.w3.org/TR/xmlschema11-1/#oc, and there's a good writeup of this at http://www.ibm.com/developerworks/library/x-xml11pt3/#N102BA.

Unfortunately, .NET doesn't support XML 1.1 as of yet I can't find any free XML 1.1 processors - but a couple of paid-for options are:

暮倦 2024-09-01 01:23:49

也许可以使用命名空间:

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

这可能会验证。

Maybe its is possible to use namespaces:

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

This will probably validate.

放赐 2024-09-01 01:23:49

我遇到了同样的问题。

因为我从 .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 设置为 English 或 CultureInfo.InvariantCulture 才能正常工作。

I faced the same problem.

Since I called the validation from .NET; I decided to suppress the specific validation error in ValidationEventHandler as a workaround. It worked for me.

    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");
        }
    }

It is important that Thread.CurrentUICulture must be set to English or CultureInfo.InvariantCulture for the current thread for this to work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文