如何在 xmlstarlet 中声明 XPath 命名空间?



我是xmlstarlet的新手,所以希望这个答案很简单。

我正在编写一个脚本来从命令行修改Inkscape SVG文件。 我选择了工具xmlstarlet。

在测试文件上测试命令语法后,我在真正的 SVG 文件上遇到了问题。 我认为命名空间的使用让我很失望。

示例文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->    
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="603"
height="1000"
viewBox="0 0 159.54375 264.58334"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r"
sodipodi:docname="test.svg"
inkscape:export-filename="/home/user/dev/inkscape/test/1.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient6204">
<stop
style="stop-color:#8f1a22;stop-opacity:1;"
offset="0"
id="stop6200" />
<stop
style="stop-color:#8f1a22;stop-opacity:0;"
offset="1"
id="stop6202" />
</linearGradient>
</defs>
</svg>

我想将Gradient6204更改为Gradient9999

我写了这个命令,它不起作用(只返回原始文件)。

xmlstarlet ed -u "/svg/defs/linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt

我也再次尝试,添加了带有 -N 的命名空间,但没有运气。 我发现如果我删除该行:

xmlns="http://www.w3.org/2000/svg"

从文件中,我上面写的命令就可以工作了。

以我描述的方式更新上述 SVG 文件的正确语法是什么?

显式命名空间声明

添加-N s=http://www.w3.org/2000/svg然后使用s:命名空间前缀有效:

xmlstarlet ed  -N s=http://www.w3.org/2000/svg -u "/s:svg/s:defs/s:linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt

默认命名空间的隐式声明

XMLStarlet v1.2.1开始,通过使用_自动绑定到默认命名空间,可以避免默认命名空间的显式命令行定义(例如 OP 的 SVG 文件的情况):

1.3. 更方便的解决方案

XML 文档还可以在任何 元素。为了处理具有更大 XMLStarlet(版本1.2.1+)将使用命名空间前缀 在输入文档的根元素上声明。默认 命名空间将绑定到前缀_DEFAULT(在版本中 1.5.0+)。

因此,上面的命令行可以重写为:

xmlstarlet ed -u "/_:svg/_:defs/_:linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt

参见

  • XML 中的命名空间和前缀有什么区别?
  • XPath 如何处理 XML 命名空间?

最新更新