如何在xmlstarlet中声明XPath命名空间? [英] How to declare XPath namespaces in xmlstarlet?
问题描述
我是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:
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屋!