我试图从XML文档中找到某个元素中的最小值(它实际上是一个转换为XML的HTML表) . 但是,这不符合预期 .
该查询类似于How can I use XPath to find the minimum value of an attribute in a set of elements?中使用的查询 . 它看起来像这样:
/table[@id="search-result-0"]/tbody/tr[
not(substring-before(td[1], " ") > substring-before(../tr/td[1], " "))
]
在示例XML上执行
<table class="tablesorter" id="search-result-0">
<thead>
<tr>
<th class="header headerSortDown">Preis</th>
<th class="header headerSortDown">Zustand</th>
</tr>
</thead>
<tbody>
<tr>
<td width="45px">15 CHF</td>
<td width="175px">Ausgepack und doch nie gebraucht</td>
</tr>
<tr>
<td width="45px">20 CHF</td>
<td width="175px">Ausgepack und doch nie gebraucht</td>
</tr>
<tr>
<td width="45px">25 CHF</td>
<td width="175px">Ausgepack und doch nie gebraucht</td>
</tr>
<tr>
<td width="45px">35 CHF</td>
<td width="175px">Ausgepack und doch nie gebraucht</td>
</tr>
<tr>
<td width="45px">14 CHF</td>
<td width="175px">Gebraucht, aber noch in Ordnung</td>
</tr>
<tr>
<td width="45px">15 CHF</td>
<td width="175px">Gebraucht, aber noch in Ordnung</td>
</tr>
<tr>
<td width="45px">15 CHF</td>
<td width="175px">Gebraucht, aber noch in Ordnung</td>
</tr>
</tbody>
</table>
查询返回以下结果:
<tr>
<td width="45px">15 CHF</td>
<td width="175px">Ausgepack und doch nie gebraucht</td>
</tr>
-----------------------
<tr>
<td width="45px">14 CHF</td>
<td width="175px">Gebraucht, aber noch in Ordnung</td>
</tr>
-----------------------
<tr>
<td width="45px">15 CHF</td>
<td width="175px">Gebraucht, aber noch in Ordnung</td>
</tr>
-----------------------
<tr>
<td width="45px">15 CHF</td>
<td width="175px">Gebraucht, aber noch in Ordnung</td>
</tr>
为什么返回的节点多于一个?应该只返回一个节点,因为只有一个最小值 . 有人看到查询有什么问题吗?它应该只返回包含 14 CHF
的节点 .
3 回答
TML已经指出了为什么你当前的路径表达式不起作用,但没有提出一个可行的替代方案 .
原因很简单,正如@Tomalak所说:
我添加这个答案来详细说明在搜索最小量的CHF之前必须预处理XML的方式 . 请记住:这很复杂,因为您在XPath 1.0中要求解决方案 . 使用XPath 2.0,您的问题可以通过单个路径表达式解决 .
XML Design
我认为您的问题说明了为什么XML设计在使用XML时实际上是必不可少的 . 为什么?因为您的问题归结为以下几点:您的XML设计方式使得操作内容变得困难 . 更准确地说,在这样的
td
元素中:td
元素的文本节点中有一个数量(作为数字)和货币 . 如果您的XML输入是以更聪明或规范的方式设计的,它看起来像:看到不同?现在,不同种类的内容明显地彼此分离 .
XPath Revised
假设在新设计的XML中,
tr/td[1]
元素的唯一内容是数字,您使用的Pavel Minaev的XPath表达式可以使用:XML Result (已通过the tool you use测试)
Why does Pavel's expression not work, simply because I add substring-before?
你已经找到了部分答案 . 它与在XPath 1.0函数中处理项目序列的方式有关 .
substring-before()
是一个XPath 1.0函数,需要两个参数,它们都是字符串 . 而且,最重要的是,如果您将字符串序列定义为substring-before()
的第一个参数,则只会处理 first string ,其他字符将被忽略 .帕维尔的回答,适应了这个问题:
依赖于表达式的第二部分
../tr/td[1]
查找tbody
的所有tr
元素的所有第一个td
子元素这一事实 . 没有涉及函数,序列作为>
的操作数没有错 .如果我们需要
substring-before()
因为文本内容实际上既是数字(我们想要的)又是货币(我们想要忽略),我们必须将它包装在表达式的两个部分:在
>
的左侧没问题,因为当前tr
只有一个td[1]
. 但是在右边,有一系列节点,即../tr/td[1]
. 可悲的是,substring-before()
只能处理第一个 .请参阅@TML的答案,了解其后果 .
XPath查询你're using here would only find the 1330788 in cases where there are no duplicate values, and the values are sorted prior to being written into nodes; this is because it'只将当前值
substring-before(td[1], " ")
与找到的第一个值substring-before(../tr/td[1], " ")
进行比较 . 要打破比较:比较1,5,6和7评估为真(左侧不大于右侧) .
与此同时,我决定使用XSLT . 这是我提出的样式表: