如何使normalize-space()xpath函数起作用?

时间:2009-12-01 21:49:50

标签: c# xpath

我目前正在尝试以下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元素)

2 个答案:

答案 0 :(得分:26)

现在你已经编辑了这个问题,这是有道理的。让我们考虑一下这个输入:

<tr><td>x</td><td>User Name</td></tr>

以及您的非工作查询:

//tr[normalize-space(td/text()) = 'User Name']

现在,td/text()表示“选择当前节点的所有子td节点的所有子文本节点”。在这种情况下,这将产生一个由两个文本节点xUser 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样本更新您的问题?