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

Joh*_*n W 10 xml xpath svg xml-namespaces xmlstarlet

我是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>
Run Code Online (Sandbox Code Playgroud)

我想换Gradient6204Gradient9999.

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

xmlstarlet ed -u "/svg/defs/linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt
Run Code Online (Sandbox Code Playgroud)

我也再次尝试,添加名称空间与-N但没有运气.我发现如果删除该行:

xmlns="http://www.w3.org/2000/svg"
Run Code Online (Sandbox Code Playgroud)

从文件然后我上面写的命令工作.

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

kjh*_*hes 11

显式命名空间声明

添加-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
Run Code Online (Sandbox Code Playgroud)

默认命名空间的隐式声明

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
Run Code Online (Sandbox Code Playgroud)