【问题标题】:XQuery looking for text with 'single' quoteXQuery 查找带有“单”引号的文本
【发布时间】:2017-06-05 00:57:01
【问题描述】:

我不知道如何使用 XPATH 搜索包含单引号的文本。

例如,我在此问题的标题中添加了引号。下面一行

$x("//*[text()='XQuery looking for text with 'single' quote']")

返回一个空数组。

但是,如果我尝试以下操作

$x("//*[text()=\"XQuery looking for text with 'single' quote\"]")

它确实返回页面标题的链接,但我希望能够在其中接受单引号和双引号,所以我不能只为单引号/双引号定制它。

您可以在此页面上的 chrome 或 firebug 的控制台中尝试。

【问题讨论】:

  • 您的第一个表达式应该在有效的 XPath 1.0 解析器中工作。您没有指定是使用 1.0 还是 2.0...来自文档:To avoid a quotation mark in an expression being interpreted by the XML processor as terminating the attribute value the quotation mark can be entered as a character reference (" or ').

标签: xpath escaping


【解决方案1】:

这是一个 hackaround(感谢 Dimitre Novatchev),它可以让我搜索 xpath 中的任何文本,无论它包含单引号还是双引号。用 JS 实现,但可以很容易地翻译成其他语言

function cleanStringForXpath(str)  {
    var parts = str.match(/[^'"]+|['"]/g);
    parts = parts.map(function(part){
        if (part === "'")  {
            return '"\'"'; // output "'"
        }

        if (part === '"') {
            return "'\"'"; // output '"'
        }
        return "'" + part + "'";
    });
    return "concat(" + parts.join(",") + ")";
}

如果我正在寻找I'm reading "Harry Potter",我可以执行以下操作

var xpathString = cleanStringForXpath( "I'm reading \"Harry Potter\"" );
$x("//*[text()="+ xpathString +"]");
// The xpath created becomes 
// //*[text()=concat('I',"'",'m reading ','"','Harry Potter','"')]

这是一个(短得多的)Java 版本。如果您删除类型信息,它与 JavaScript 完全相同。感谢https://stackoverflow.com/users/1850609/acdcjunior

String escapedText = "concat('"+originalText.replace("'", "', \"'\", '") + "', '')";!

【讨论】:

  • Juan,我很高兴我对您的 cmets 的回答导致了解决方案。请考虑接受我的回答。
  • @DimitreNovaatchev 您的答案没有我在答案中输入的信息,真正的技巧隐藏在 cmets 中。我的回答基于您的回答,但您的回答并未具体回答我的问题。如果你改进你的具体解决我的问题,我会接受它。
  • 这是 XPath 1.0 中最好的一个。如果表达式是 XML 文档的一部分,则可以使用 "' 这两个实体——但这不是您的情况。我可以提供一个 C# 解决方案,但是您似乎使用的是 Javascript,我不太流利。
  • @DimitreNovaatchev 我只是说要让你的答案真正回答这个问题,它至少必须指定你需要用concat() 包装你的整个字符串,然后你可以运行替换以将'" 更改为"'"'"'。您不必像我一样编写代码。 JS 只是解释它需要什么的最快方法。我实际上正在编写一个我真正要使用的 Java 版本。现在的答案看起来你误解了这个问题
  • 这个理由很有用!帮助很大!我在 Java 中使用了这个:String escapedText = "concat('"+originalText.replace("'", "', \"'\", '") + "', '')";!
【解决方案2】:

在 XPath 2.0 和 XQuery 1.0 中,字符串文字的分隔符可以通过加倍包含在字符串文字中:

let $a := "He said ""I won't"""

let $a := 'He said "I can''t"'

约定是从 SQL 借来的。

【讨论】:

  • 这个答案很有趣。但是我在 Firefox 中使用 Selenium,可惜他们似乎支持 XPath 但不支持 XPath 2。我说他们似乎,这几乎没有文档记录。
【解决方案3】:

这是一个例子

/*/*[contains(., "'") and contains(., '"') ]/text()

当此 XPath 表达式应用于以下 XML 文档时:

<text>
    <t>I'm reading "Harry Potter"</t>
    <t>I am reading "Harry Potter"</t>
    <t>I am reading 'Harry Potter'</t>
</text>

选择了想要的正确结果(单个文本节点):

I'm reading "Harry Potter"

这里是使用XPath Visualizer(我在 12 年前创建的免费开源工具,它已将 XPath 以有趣的方式传授给成千上万的人)的验证:

您的问题可能是您无法在您正在使用的编程语言中将此 XPath 表达式指定为字符串 - 这不是 XPath 问题,而是您对编程语言的了解方面的问题。

【讨论】:

  • 您的答案告诉您如何通过硬编码双引号内的单引号 ("'") 和单引号内的双引号 ('"') 来查找包含单引号和双引号的文本节点.但是,我需要的是一个查询,该查询将使用 //div[text()="I'm reading "Harry Potter""] 之类的查询搜索特定文本...显然,我的示例没有正确转义引号。我希望//*[text()='I&amp;#39;m reading &amp;#34;Harry Potter&amp;#34;'] 能够工作
  • 不,问题不在于“我对编程语言的了解”。问题是关于如何在 XPath 中的引用内容中转义引号
  • 为此,需要知道字符串的哪一部分包含双引号或单引号。我不能这样做,要搜索的文本超出了我的控制范围,它被交给了一个方法,我必须为它创建一个 XPATH。同样,我不能只使用反向引用,因为这需要提前知道要搜索的字符串
  • 双引号不起作用,不确定浏览器是否支持 XPath 2.0。以下不会产生任何结果:$x("//*[text()=\"XQuery looking for text with ''single'' quote\"]")
  • XPath 2.0 在任何浏览器中均不受支持。我对您将 XQuery 一词与 Chrome 和 firebug 一起使用感到惊讶。
【解决方案4】:

此外,如果您使用的是 XQuery,而不是 XPath,如标题所述,您还可以使用 xml 实体:

   "&quot; for double and &apos; for single quotes"

它们也可以在单引号内工作

【讨论】:

  • 我不确定您所说的使用 XQuery 而不是 XPath 是什么意思,您能详细说明一下吗?我正在使用 Selenium 编写自动化测试
  • 好吧,您在标题中提到了 XQuery。我不知道 Selenium 是否支持 XQuery。无论如何,那里的字符串支持基本的 xml 实体,而 XPath 不支持。 (比较XQueryXPath 标准)
【解决方案5】:

您可以使用正则表达式来做到这一点。例如(作为 ES6 代码):

export function escapeXPathString(str: string): string {
    str = str.replace(/'/g, `', "'", '`);

    return `concat('${str}', '')`;
}

这会将输入字符串中的所有' 替换为', "'", '

最后的, '' 很重要,因为concat('string') 是一个错误。

【讨论】:

  • 如果'是第一个字符会发生什么?
  • 好主意,但当引号是第一个或最后一个字符时不起作用。
【解决方案6】:

好吧,我也在做同样的事情,但过了一会儿,我发现 xpath 对此没有支持,真是令人失望!但是,我们总是可以解决它!

我想要一些简单直接的东西。我带来的是设置你自己的撇号替换,一种独特的代码(你不会在你的 xml 文本中遇到的东西),我选择了 //apos// 例如。现在你 把它放在你的 xml 文本和你的 xpath 查询中 。 (如果你不是总是写 xml,我们可以用任何编辑器的替换功能替换)。 现在我们该怎么做?我们用这个正常搜索,检索结果,并将 //apos// 替换回 '.

下面是我正在做的一些示例:(replace_special_char_xpath() 是你需要做的)

function repalce_special_char_xpath($str){
    $str = str_replace("//apos//","'",$str);
    /*add all replacement here */
    return $str;
}

function xml_lang($xml_file,$category,$word,$language){ //path can be relative or absolute
    $language = str_replace("-","_",$language);// to replace - with _ to be able to use "en-us", .....
    $xml = simplexml_load_file($xml_file);
    $xpath_result = $xml->xpath("${category}/def[en_us = '${word}']/${language}");
    $result = $xpath_result[0][0];
    return repalce_special_char_xpath($result);
}

xml文件中的文本:

<def>
     <en_us>If you don//apos//t know which server, Click here for automatic connection</en_us>   <fr_fr>Si vous ne savez pas quelle serveur, Cliquez ici pour une connexion automatique</fr_fr>    <ar_sa>إذا لا تعرفوا أي سرفير, إضغطوا هنا من أجل إتصال تلقائي</ar_sa>
</def>

和php文件中的调用(生成的html):

<span><?php echo xml_lang_body("If you don//apos//t know which server, Click here for automatic connection")?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多