如何使用 xmlstarlet 在另一个元素下插入一个新元素?
$ vim test.xml
<?xml version="1.0" encoding="UTF-8" ?>
<config>
</config>
$ xmlstarlet ed -i "/config" -t elem -n "sub" -v "" test.xml
<?xml version="1.0" encoding="UTF-8"?>
<sub></sub>
<config>
</config>
但我希望 sub 成为 config 的子项。我应该如何更改 -i 的 xpath 参数?
奖金: 是否可以直接使用属性插入子项,甚至将其设置为一个值? 像这样的东西:
$ xmlstarlet ed -i "/config" -t elem -n "sub" -v "" -a attr -n "class" -v "com.foo" test.xml
$ vim test.xml
<?xml version="1.0" encoding="UTF-8" ?>
<config>
</config>
$ xmlstarlet ed -i "/config" -t elem -n "sub" -v "" test.xml
<?xml version="1.0" encoding="UTF-8"?>
<sub></sub>
<config>
</config>
But I wanted sub to be a child of config. How should I change the xpath parameter of -i?
BONUS:
Is it possible to insert the child directly with an attribute and even have it set to a value?
Something like:
$ xmlstarlet ed -i "/config" -t elem -n "sub" -v "" -a attr -n "class" -v "com.foo" test.xml
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我遇到了类似的问题:我有一个 Tomcat 配置文件 (server.xml),并且必须将带有预定义属性的< /代码> 部分。
标记插入这是它之前的样子:
这是我想要实现的目标:
这是我的做法(来自 shell 脚本的片段):
诀窍是临时为新元素指定一个唯一的名称,以便以后可以找到它带有 XPATH 表达式。添加所有属性后,名称将更改回 Resource(使用 -r)。
其他xmlstarlet选项的含义:
I had a similar problem: I had a Tomcat configuration file (server.xml), and had to insert a
<Resource>
tag with pre-defined attributes into the<GlobalNamingResources>
section.Here is how it looked before:
Here is what I wanted to achieve:
Here is how I did it (snippet from a shell script):
The trick is to temporarily give a unique name to the new element, so that it can be found later with an XPATH expression. After all attributes have been added, the name is changed back to Resource (with -r).
The meaning of the other xmlstarlet options:
使用
-s
(或--subnode
)而不是-i
。关于好处,您不能直接插入带有属性的元素,但由于每个编辑操作都是按顺序执行的,因此插入元素然后添加属性:Use
-s
(or--subnode
) instead of-i
. Regarding the bonus, you can't insert an element with an attribute directly but since every edit operation is performed in sequence, to insert an element and then add an attribute:从 XMLStarlet 1.4.0 版(日期为 2012-08-26)开始,您可以使用
$prev
(或$xstar:prev
)作为- 的参数i
、-a
和-s
引用最后插入的节点集。请参阅文件doc/xmlstarlet.txt
,
examples/ed-backref1
、examples/ed-backref2
和examples/ed-backref-delete
。您不再需要使用使用临时元素名称插入元素然后在最后重命名的技巧。该示例examples/ed-backref2
特别有用展示如何定义一个变量来引用先前创建的注释,这样您就不需要执行诸如$prev/..
之类的技巧来“导航”出一个节点。From version 1.4.0 of XMLStarlet (dated 2012-08-26), you can use
$prev
(or$xstar:prev
) as the argument to-i
,-a
, and-s
to refer to the last nodeset inserted. See the examples in the XMLStarlet source code in the filesdoc/xmlstarlet.txt
,examples/ed-backref1
,examples/ed-backref2
, andexamples/ed-backref-delete
. You no longer need to use the trick of inserting the element with a temporary element name and then renaming it at the end. The exampleexamples/ed-backref2
is particularly helpful in showing how to define a variable to use to refer to a (the) previously-created note so that you don't need to do tricks such as$prev/..
to "navigate" out of a node.正如@npostavs提到的,正确的答案是使用“子节点”。要使用新的“$prev”改进答案,您可以执行以下操作:
使用以下说明:
As mentioned by @npostavs the correct answer is to use 'subnode'. To improve the answer with the new '$prev' you can do the following:
With the following explanation:
直到我将
包装到
元素中后,该示例才起作用。The example did not work until I wrapped
<GlobalNamingResources>
into a<Server>
element.我尝试了上面的 cellux 的技巧。效果很好!谢谢!!
但是,格式没有保留,只是为了尝试,我去掉了选项 -P 和 -S,格式问题就消失了!我正在使用 CentOS。也许这可以帮助某人。
I tried the trick from cellux above. It worked great! Thanks!!
But, the formatting was not persisted, just to try, I got rid of options -P and -S, and the formatting issues were gone! I am using CentOS. May be this can help someone.