如何在xmlstarlet中声明XPath命名空间? [英] How to declare XPath namespaces in xmlstarlet?

查看:90
本文介绍了如何在xmlstarlet中声明XPath命名空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to xmlstarlet so hoping this answer is a simple one.

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

I am writing a script to modify Inkscape SVG files from the command line. I chose the tool xmlstarlet.

在测试文件上测试命令语法后,我在真正的SVG文件上遇到了麻烦.我认为命名空间的使用使我失望.

After testing the command syntax on test files, I am having trouble on the real SVG files. I think the use of namespaces is throwing me off.

<?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.

I want to change Gradient6204 to Gradient9999.

我编写了此命令,该命令不起作用(仅返回原始文件).

I wrote this command, which does not work (just returns the original file).

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

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

I also tried again, adding the namespaces with -N but no luck. I found that if I delete the line:

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

从文件中删除,然后我上面编写的命令起作用.

from the file then the command I wrote above works.

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

What is the proper syntax for updating the SVG file above in the way I described?

推荐答案

显式命名空间声明

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

Explicit Namespace Declaration

Adding -N s=http://www.w3.org/2000/svg and then using the s: namespace prefix works:

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文件的情况).到默认名称空间:


Implicit Declaration of Default Namespace

Starting with XMLStarlet v1.2.1, an explicit command line definition for the default namespace (such as is the case with OP's SVG file) can be avoided via use of an automated binding of _ to the default namespace:

1.3.更加方便的解决方案

XML文档还可以在任何位置使用不同的名称空间前缀 文档中的元素.为了处理更大的名称空间 轻松,XMLStarlet(版本1.2.1+)将使用名称空间前缀 在输入文档的根元素上声明.默认值 名称空间将绑定到前缀_DEFAULT(在版本中 1.5.0 +).

XML documents can also use different namespace prefixes, on any element in the document. In order to handle namespaces with greater ease, XMLStarlet (versions 1.2.1+) will use the namespace prefixes declared on the root element of the input document. The default namespace will be bound to the prefixes _ and DEFAULT (in versions 1.5.0+).

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

So, the above command line could be re-written as:

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

这篇关于如何在xmlstarlet中声明XPath命名空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆