我目前正在尝试以下xpath
//tr[normalize-space(td/text())='User Name']
获取包含td的所有tr,其中包含'User Name'
或'User Name'
或' User Name '
但它不起作用且我不知道查询有什么问题:(<登记/>
我想要找到的数据采用以下格式
<tr><td>User Name</td></tr>
<tr><td>User Name</td></tr>
<tr><td> User Name </td></tr>
那么编写这个xpath查询的正确格式是什么?
编辑: 如果数据采用以下格式,似乎无法正常工作
<tr><td>x</td><td>User Name</td></tr>
<tr><td>x</td><td>y</td><td>User Name</td></tr>
<tr><td>x</td><td>y</td><td>z</td><td> User Name </td></tr>
所以现在我该如何编写xpath查询?
注意:“// tr [normalize-space(td / text())='用户名']”不工作
但是“// tr / td [normalize-space(text())='用户名']”将起作用(但我想得到tr而不是td元素)
答案 0 :(得分:26)
现在你已经编辑了这个问题,这是有道理的。让我们考虑一下这个输入:
<tr><td>x</td><td>User Name</td></tr>
以及您的非工作查询:
//tr[normalize-space(td/text()) = 'User Name']
现在,td/text()
表示“选择当前节点的所有子td
节点的所有子文本节点”。在这种情况下,这将产生一个由两个文本节点x
和User Name
组成的节点集。
现在,您在该节点集上调用normalize-space()
。 normalize-space()
唯一参数的类型是string?
。由于节点集不是字符串,因此每次section 3.2 XPath 1.0建议都会产生转换:
将参数转换为类型字符串,就像调用string()函数一样。
现在让我们看一下4.2节中的definition字符串():
通过返回文档顺序中第一个的节点集中节点的字符串值,将节点集转换为字符串。如果节点集为空,则返回空字符串。
在我们的示例中,第一个节点“按文档顺序”是文本节点x
,因此它将被使用;第二个节点被忽略。因此,您最终会调用normalize-space('x')
。当然,这不会与“用户名”相提并论。要使其工作,请使用:
//tr[td[normalize-space(text()) = 'User Name']]
这可以转录为“选择具有子tr
个节点的所有td
个节点,其中第一个子text()
节点的标准化字符串值为User Name
” - 这就是你想要的。此外,您可以将其简化为:
//tr[td[normalize-space() = 'User Name']]
由于无参数normalize-space()
将应用于当前节点(将为td
),并处理其中的所有文本节点。
答案 1 :(得分:1)
这在这里工作正常:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(@"
<table>
<tr><td>User Name</td></tr>
<tr><td> User Name </td></tr>
<tr><td> User Name </td></tr>
</table>");
Console.WriteLine(
xmlDoc.SelectNodes(
"//tr[td[normalize-space(.) = 'User Name']]").Count); // shows "3"
您能否使用实际的XML样本更新您的问题?