在xpath中同时转义双引号和单引号

问题描述 投票:0回答:2

赏金:目前的答案还没有完全解决。

更新:非常欢迎我尝试将“ R转换为R”的非R答案!

类似于How to deal with single quote in xpath,我想转义单引号。区别在于我无法排除在目标字符串中也可能出现双引号的可能性。

目标:

同时使用xpath(在R中,转义双引号和单引号)。目标元素应该用作变量,而不像现有答案之一那样被硬编码。 (它应该是一个变量,因为我事先不知道Content,它可以有单引号,双引号或两者都有)。

Works:

library(rvest)
library(magrittr)
html <- "<div>1</div><div>Father's son</div>"
target <- "Father's son"
html %>% xml2::read_html() %>% html_nodes(xpath = paste0("//*[contains(text(), \"", target,"\")]"))
{xml_nodeset (1)}
[1] <div>Father's son</div>

不起作用:

html <- "<div>1</div><div>Fat\"her's son</div>"
target <- "Fat\"her's son"
html %>% xml2::read_html() %>% html_nodes(xpath = paste0("//*[contains(text(), \"", target,"\")]"))
{xml_nodeset (0)}
Warning message:
In xpath_search(x$node, x$doc, xpath = xpath, nsMap = ns, num_results = Inf) :
  Invalid expression [1207]
r xpath escaping quotes rvest
2个回答
1
投票

quote()用于xpath查询

library(XML)

字符串中仅单引号

target1 <- "Father's son"
doc1 <- XML::newHTMLDoc()
newXMLNode("div", 1, parent = getNodeSet(doc1, "//body"), doc = doc1)
newXMLNode("div", target1, parent = getNodeSet(doc1, "//body"), doc = doc1)
xpath_query1 <- paste0('//*[ contains(text(), ', '"', target1, '"', ')]')
getNodeSet(doc1, xpath_query1)

字符串中的单引号和双引号都包含

target2 <- "Fat\"her's son"
doc2 <- XML::newHTMLDoc()
newXMLNode("div", 1, parent = getNodeSet(doc2, "//body"), doc = doc2)
newXMLNode("div", target2, parent = getNodeSet(doc2, "//body"), doc = doc2)
xpath_query2 <- quote('//body/*[contains(.,concat(\'Fat"\',"her\'s son"))]')
getNodeSet(doc2, xpath_query2)

输出:

getNodeSet(doc1, xpath_query1)
# [[1]]
# <div>Father's son</div> 
# 
# attr(,"class")
# [1] "XMLNodeSet"

getNodeSet(doc2, xpath_query2)
# [[1]]
# <div>Fat"her's son</div> 
# 
# attr(,"class")
# [1] "XMLNodeSet"

0
投票

由于您正在使用字符串操作来构建XPath表达式,因此该表达式是有效的XPath是您的责任。这个表达式:

//*[contains(.,concat('Fat"',"her's son"))]

选择:

<div>Fat"her's son</div>

here中测试

使用XPath字符串变量是一种更好的方法,但是看起来R甚至没有使用libxml的API。

© www.soinside.com 2019 - 2024. All rights reserved.