使用XPath查找包含空格的节点值

12

我需要使用XPath根据节点的值定位xml文件中的节点。

当要查找的节点包含内部空格时,问题就会出现。例如:

<Root>
  <Child>value</Child>
  <Child>value with spaces</Child>
</Root>

我无法构建XPath定位到第二个子节点。

简单的XPath /Root/Child 可以完美地适用于两个子节点,但是 /Root[Child=value with spaces] 返回一个空集合。

我已经尝试使用%20& #20;& nbsp; 进行空格掩码处理,并使用引号和双引号。

仍然没有成功。

有人有想法吗?

7个回答

21
根据您的具体情况,有不同的XPath表达式可以选择包含一些空格的节点。
首先,让我们回想一下任何一个这些字符都是“空格”:
-- Tab
-- 换行符
-- 回车符
' ' 或 -- 空格
如果您知道节点的确切值,比如它是带有一个空格的"Hello World",那么最直接的XPath表达式是:
/top/aChild[. = 'Hello World']
将选择此节点。
然而,指定包含空格的值的困难在于我们认为所有空格字符都只是... 嗯,空格,而不知道它是一组空格还是一个制表符。 XPath 2.0中可以使用正则表达式,它们提供了简单和方便的解决方案。因此,我们可以使用XPath 2.0表达式,如下所示:
/*/aChild[matches(., "Hello\sWorld")]
要选择顶级节点的任何子节点,其值为字符串"Hello"后跟空格,然后是字符串"World"。请注意使用matches()函数和匹配空格的"\s"模式。注意
XPath 1.0中,如果给定的字符串包含任何空格字符,则可以方便地测试如下: not(string-length(.)= stringlength(translate(., ' &#9;&#xA;&#xD;',''))) 我们在此处使用translate()函数来消除四个空格字符之一,并将结果字符串的长度与原始字符串的长度进行比较。
因此,如果在文本编辑器中,节点的值显示为
"Hello    World",
我们可以使用XPath表达式安全地选择此节点: /*/aChild[translate(., ' &#9;&#xA;&#xD;','') = 'HelloWorld'] 在许多情况下,我们还可以使用XPath函数normalize-space(),它从其字符串参数生成另一个字符串,在该字符串中,前导和尾随空格的组被去除,并且字符串中的每个空格都被替换为单个空格。
在上述情况中,我们将仅使用以下XPath表达式: /*/aChild[normalize-space() = 'Hello World']

@DimitreNovatchev,您能否提供一个文档,其中包含这样的编码列表,例如* -- Tab*。 - Arup Rakshit
@Babai,空格字符只有这三个: - Dimitre Novatchev
@DimitreNovatchev 我在谈论其他人是否还有更多的问题..好的。谢谢您的及时回复..这里有一个非常好的问题。您能帮助OP吗?我正在尝试,但无法构思..您有时间吗,先生? - Arup Rakshit
1
@Babai,很抱歉我这些天非常忙。你需要查看Unicode标准(http://www.unicode.org/)。 - Dimitre Novatchev
@Babai,你正在将一个换行符添加到concat()函数的第一个参数中取出的第一个节点的字符串值中——你确定这真的是你想要的吗? - Dimitre Novatchev
显示剩余6条评论

10

可以尝试以下两种方法:

/Root/Child[normalize-space(text())=value without spaces]
或者
/Root/Child[contains(text(),value without spaces)]

或者(因为看起来你的测试值可能是问题所在)

/Root/Child[normalize-space(text())=normalize-space(value with spaces)]

我实际上并没有执行这些代码,所以语法可能有点奇怪。


Dimitre Novatchev的回答非常详细,但我认为对于大多数情况来说有些过度了。我会点赞这个回答,因为它更简单,并且适用于大多数情况。至少在精神上是这样的:)-函数是normalize()而不是normalize-space()。请参见:normalize-space函数的官方文档。 - Michael Sorens

2

使用XPath定位包含空格的属性值

我有一个包含空格的输入类型元素。

例如:

<input type="button"  value="Import&nbsp;Selected&nbsp;File">

我使用以下xpath表达式解决了这个问题。
//input[contains(@value,'Import') and contains(@value ,'Selected')and contains(@value ,'File')]

希望这可以帮助你们。

好的,它也会匹配“文件已选择导入”,这有时可能是一个陷阱,在我的情况下肯定是不可取的。 - user15108

1
"x0020"在一个基于Jackrabbit的CQ5/AEM仓库中对我有用,该仓库的属性名称包含空格。下面的代码可以适用于一个名为"Record ID"的属性-
[(jcr:contains(jcr:content/@Record_x0020_ID, 'test'))]

0
以上所有的解决方案对我都没有起作用。 然而,有一个更简单的解决方案。
在创建XMLDocument时,请确保将 PreserveWhiteSpace 属性设置为 true;
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.PreserveWhitespace = true;
        xmldoc.Load(xmlCollection);

0

你试过 #x20 吗?


0

我已经在第二个链接上谷歌了这个问题:

尝试使用“x0020”替换空格

这似乎对那个人有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接