我可以针对XML模式验证XPath表达式吗?

时间:2009-03-21 05:42:18

标签: .net xml xpath xsd

您可以针对XML文档验证XPath表达式以验证它,但是有一种简单的方法可以针对该文档的架构验证相同的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...

......虽然我知道如果我真的不得不这样做,我可以这样做。

干杯!

2 个答案:

答案 0 :(得分:6)

我们实际上做了一个研究项目,并在2000年左右实现了一个XPath验证程序。这是针对XPath 1.我不知道你可以使用任何当前可用的库。

如果你想自己去实现这个,这里有一些提示:

  • 您将无法像上面那样将实例文档上的路径转换为架构上的路径。例如,/a//b不会转换为/xsd:element[@name='a']//xsd:element[@name='b'],因为元素b可能在架构的顶层定义,而不是在b下面。

  • 请记住,虽然XML文档是树,但架构是图形。如果你搜索像// a这样的后代路径,你将不得不决定何时终止搜索,或者它可以永久地继续(例如想象在包含“b”的元素“a”中,其中包含“a”)

  • 有些路径是不可判定的,或者至少很难决定。例如//*[starts-with(@name, 'foo')]

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

答案 1 :(得分:3)

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

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

我不会尝试直接评估针对架构的XPath,因为各种Axes会使完整的解决方案非常复杂。我很确定可以做到,但它让我感觉像是核心数学。我建议生成样本作为捷径。