我可以根据 XML 模式验证 XPath 表达式吗?

问题描述 投票:0回答:3

您可以根据 XML 文档验证 XPath 表达式来验证它,但是有没有一种简单的方法可以根据该文档的schema 验证相同的 XPath 表达式?

假设我有一个像这样的 XSD 架构:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" ... etc>
  <xsd:element name="RootData">
    <xsd:complexType>
      <xsd:sequence minOccurs="0">
        <xsd:element name="FirstChild">
          <xsd:complexType>
            <xsd:sequence minOccurs="0">
              <xsd:element name="FirstGrandChild">
... etc etc

是否有一种简单或内置的方法来验证 XPath:

/RootData/FirstChild/FirstGrandChild

对于任何可能基于该模式的 XML 文档都有效吗? (编辑:我想我的意思是潜在有效实际 XML 文档可能不包含这些元素,但 XPath 仍然可以被视为对架构潜在有效。而,

/RootData/ClearlyInvalidChild/ThisElementDoesntExistEither
显然是无效的。 )

当然,我只能期望它适用于规范的 XPath 表达式,而不是任意复杂的表达式,但这很好。

我特别在 .NET 中思考,但很好奇其他实现是否使之成为可能。我想要自己推出并不那么重要,例如,我真的不想编写自己的代码来将该 XPath 表达式转换为另一个表达式,例如:

/xsd:schema/xsd:element[@name='RootData']/xsd:complexType/xsd:sequence/xsd:element[@name='FirstChild']/...etc...

...虽然我知道如果我真的需要的话我可以做到。

干杯!

.net xml xpath xsd
3个回答
6
投票

我们实际上对此做了一个研究项目,并在 2000 年左右的某个时候实现了一个 XPath 验证器。这是针对 XPath 1 的。我不知道当前有任何可用的库可以用来执行此操作。

如果您想自己实现这一点,这里有一些提示:

  • 您将无法像上面那样将实例文档上的路径转换为架构上的路径。例如,

    /a//b
    不会转换为
    /xsd:element[@name='a']//xsd:element[@name='b']
    ,因为元素 b 可能定义在模式的顶层,而不是 b 之下。

  • 请记住,XML 文档是树,而模式是图。如果您搜索像 //a 这样的后代路径,您将必须决定何时终止搜索,否则搜索可能会永远继续下去(例如,想象一个元素“a”包含“b”,其中包含“a”)

  • 有些路径是无法决定的,或者至少很难决定。例如

    //*[starts-with(@name, 'foo')]

如果您仍然想这样做,我建议使用像 eclipse 的 XSD 这样的库或 .NET 模式加载类将模式加载到内存中并检查代码。


3
投票

在设计时,您可以使用工具生成示例 XML 文档并针对该示例执行 XPath。 Altova XML Spy 具有此功能,SOAP UI 也具有此功能。

SOAP UI 实际上是开源的(Java),所以也许您可以看一下它是如何生成示例的。在运行时情况下(即,如果模式和 XPath 都是正在运行的程序的输入),那么您必须确保生成足够的可选组件和示例数据以避免漏报,并且可能需要生成多个示例文件。

我不会尝试直接根据模式评估 XPath,因为各种轴会使完整的解决方案变得非常复杂。我很确定这是可以做到的,但它给我的印象是核心数学。我建议将生成样本作为捷径。


0
投票

我刚刚发现这个老问题,并认为它需要一个正确的答案。

自 2.0 版(2007 年发布)以来,XPath、XSLT 和 XQuery 规范定义了模式感知处理的选项。没有多少处理器实现此选项(Saxon-EE 就是其中之一),但该选项已在规范中定义。

我在这里写了一篇关于模式感知处理的旧文章:https://www.stylusstudio.com/schema-aware.html - 其中大部分内容在今天同样有效。

© www.soinside.com 2019 - 2024. All rights reserved.