通过XMLStarlet Unescape&符号(&) - Bugging&

时间:2017-09-16 15:08:14

标签: bash shell escaping wget xmlstarlet

这是一个非常烦人但相当简单的任务。根据这个guide,我写了这个:

<?php

    $currentUser = $_SESSION['id'];
    $sql = "SELECT username FROM user WHERE id='$currentUser'";
    $result = mysqli_query($conn, $sql);
    $getResult = mysqli_fetch_assoc($result);
    $author = $getResult['username'];

    $sql2 = "SELECT * FROM image WHERE author='$author' ORDER BY id DESC";
    $result2 = mysqli_query($conn, $sql2);
    $getResult2 = mysqli_fetch_assoc($result2);

    while ($row = $result2->fetch_assoc()){
        echo '<a href="imageInfo.php?image='.$row["path"].'"><img class="profilePageImages" src="uploads/'.$row['path'].'" alt="Random image" /></a>';
    }

?>

我成功地从表格中提取每个链接并且所有内容都正确连接,但是,不是将&符号再现为&amp; ,而是在每个链接的末尾都会收到此信息:

#!/bin/bash

content=$(wget "https://example.com/" -O -)
ampersand=$(echo '\&')

xmllint --html --xpath '//*[@id="table"]/tbody' - <<<"$content" 2>/dev/null |
    xmlstarlet sel -t \
        -m "/tbody/tr/td" \
            -o "https://example.com" \
            -v "a//@href" \
            -o "/?A=1" \
            -o "$ampersand" \
            -o "B=2" -n \

但实际上,我正在寻找类似的东西:

https://example.com/hello-world/?A=1\&amp;B=2

我们的想法是使用反斜杠https://example.com/hello-world/?A=1&B=2 来转义角色,以便忽略它。最初,我尝试将其直接放入\&而不是-o "\&" \,并在这种情况下删除-o "$ampersand" \。结果仍然相同。

基本上,通过删除反斜杠,它仍会输出:

ampersand=$(echo '\&')

仅删除https://example.com/hello-world/?A=1&amp;B=2 后面的\

为什么?

我确信这是基本缺失的东西。

3 个答案:

答案 0 :(得分:2)

&amp;是在XML文档中打印&的正确方法,但由于您只需要一个普通的URL,因此输出不应该是XML。因此,您需要通过将--text-T传递给sel命令来切换到文本模式。

您的示例输入不太起作用,因为example.com没有任何table个元素,但这是一个工作示例,而是构建来自p元素的链接。

content=$(wget 'https://example.com/' -O -)
xmlstarlet fo --html <<<"$content" |
    xmlstarlet sel -T -t \
        -m '//p[a]' \
            --if 'not(starts-with(a//@href,"http"))' \
              -o 'https://example.com/' \
            --break \
            -v 'a//@href' \
            -o '/?A=1' \
            -o '&' \
            -o 'B=2' -n

输出

http://www.iana.org/domains/example/?A=1&B=2

答案 1 :(得分:1)

正如您已经看到的,反斜杠逃避不是解决方案。我可以想到两个可能的选择:

提取href(可能不需要使用 xmllintxmlstarlet来执行此操作),然后使用标准文本处理工具,例如{ {1}}添加开头和结尾:

sed

或者,将您当前获得的内容输出到sed 's,^,https://example.com/,; s,$,/?A=1\&B=2,' ,这会将xmlstarlet unesc更改为&amp;

答案 2 :(得分:1)

抱歉,我无法重现您的结果,但为什么不进行替换?只需通过

过滤结果
sed 's/\\&amp;/\&/g'

将它添加到您的管道中。它应该取代所有&amp; amp; amp;到&amp;。