1

我有以下函数可以在 a 中查找值HTML DOM

它可以工作,但是当我给出以下参数时$valueLevi's Baby Overall, 它会破裂,因为它不会逃脱 , 和 ' 字符

如何从 DOM XPath 查询中转义所有无效字符?

private function extract($file,$url,$value) {
    $result = array();
    $i = 0;
    $dom = new DOMDocument();
    @$dom->loadHTMLFile($file);
    //use DOMXpath to navigate the html with the DOM
    $dom_xpath = new DOMXpath($dom);
    $elements = $dom_xpath->query("//*[text()[contains(., '" . $value . "')]]");
    if (!is_null($elements)) {
        foreach ($elements as $element) {
            $nodes = $element->childNodes;
            foreach ($nodes as $node) {
                if (($node->nodeValue != null) && ($node->nodeValue === $value)) {
                    $xpath = preg_replace("/\/text\(\)/", "", $node->getNodePath());
                    $result[$i]['url'] = $url;
                    $result[$i]['value'] = $node->nodeValue;
                    $result[$i]['xpath'] = $xpath;
                    $i++;
                }
            }
        }
    }
    return $result;
}
4

2 回答 2

1

不应该用用户提供的任意字符串替换 XPath 表达式中的占位符——因为存在(恶意)XPath 注入的风险。

为了安全地处理此类未知字符串,解决方案是使用预编译的 XPath 表达式并将用户提供的字符串作为变量传递给它。这也完全消除了在代码中处理嵌套引号的需要。

于 2012-10-24T04:22:16.753 回答
1

PHP 没有用于为 XPath 查询转义/引用字符串的内置函数。此外,为 XPath 转义字符串非常困难,以下是有关原因的更多信息:https ://stackoverflow.com/a/1352556/1067003 ,这是他的 C# XPath 引用函数的 PHP 端口:

function xpath_quote(string $value):string{
    if(false===strpos($value,'"')){
        return '"'.$value.'"';
    }
    if(false===strpos($value,'\'')){
        return '\''.$value.'\'';
    }
    // if the value contains both single and double quotes, construct an
    // expression that concatenates all non-double-quote substrings with
    // the quotes, e.g.:
    //
    //    concat("'foo'", '"', "bar")
    $sb='concat(';
    $substrings=explode('"',$value);
    for($i=0;$i<count($substrings);++$i){
        $needComma=($i>0);
        if($substrings[$i]!==''){
            if($i>0){
                $sb.=', ';
            }
            $sb.='"'.$substrings[$i].'"';
            $needComma=true;
        }
        if($i < (count($substrings) -1)){
            if($needComma){
                $sb.=', ';
            }
            $sb.="'\"'";
        }
    }
    $sb.=')';
    return $sb;
}

示例用法:

$elements = $dom_xpath->query("//*[contains(text()," . xpath_quote($value) . ")]");
  • 请注意我没有"在 xpath 本身中添加引用字符 ( ),因为 xpath_quote 函数为我完成了它(或 concat() 等效项,如果需要)
于 2017-07-21T02:45:56.443 回答