通过XPath查找xml中未引用的变量

时间:2018-08-23 20:50:55

标签: xpath

以下XML结构是给定屏幕的元数据的示例:

<page>
    <context>
        <variable name="used" type="String" />
        <variable name="unused" type="String" />
        <variable name="temp" type="Number" />
    </context>
    <actions>
        <assign>
             <from>"Test"</from>
             <to>used</to>
        </assign>
        <assign>
             <from>1</from>
             <to>temp</to>
        </assign>
    </actions>
 </page>

我正在寻找一个XPath表达式,该表达式可以向我返回页面中未引用的变量列表。在此示例中,它是未使用变量。

鉴于:

not(/page/actions//*/text() = 'unused') => Returns true (unreferenced)
not(/page/actions//*/text() = 'used') => Returns false

/page/context/variable[not(/page/actions//*/text() = @name)] => Return unused variable node
/page/context/variable[/page/actions//*/text() = @name] => Returns the used and temp variable node

这一切都可以,只要文本与变量名完全匹配即可。但是,由于文本是一个表达式,因此它不仅可以包含变量名,而且可以在字符串的任何位置包含

因此,我想到了使用包含(干草堆,针叶)的容器来完成上述操作。

鉴于:

/page/actions//*[contains(text() , 'temp')] => Returns the temp variable node
not(/page/actions//*[contains(text() , 'unused')]) => Returns true

我认为其中之一会起作用:

/page/context/variable[not(/page/actions//*[contains(text(), @name)])]

我认为@name不起作用,因为它不在变量节点的范围内,而是/// *

中的那个

也不

/page/context/variable[not(contains(/page/actions//*/text(), @name))]

返回所有3个变量。

有人可以指导我吗?

  1. 为什么它与相等一起工作而不与包含一起工作?
  2. 什么表达式可以返回正确的结果?

理想情况下,这是通过使用XPath规范的1.0版来实现的。

1 个答案:

答案 0 :(得分:1)

之所以能够与等式一起工作,是因为您的谓词正在过滤/page/context/variable元素,因此@name引用了该变量元素的属性,而=是一个集合比较,可以测试(多个)/page/actions//text()节点值是否等于(单个)@name

您尝试将contains()用于以下XPath的两个问题:

  1. 在操作元素上的谓词过滤器中,@name将解析为谓词正在过滤的上下文元素的名称属性。它不知道您是指/page/context/variable元素的name属性。
  2. 可以有多个text(),并且contains()期望第一个参数为单个项目。

XPath 2.0 或更高版本中,您可以使用以下XPath,该XPath将@name绑定到变量,然后测试{ {1}}包含变量text()的值。

/page/actions