在 XML 文件中,用于取消嵌入指定标记内的标记字符链的 xmlstarlet 命令是什么?
示例:搜索标记的每个出现位置<b>
,仅当它在标记内时才需要删除<c> ... </c>
:
- 输入示例:
<c>This is <b>an example</b>. <a>This is <b>a test;</b></a></c>
- 期望的输出:
<c>This is an example. <a>This is <b>a test;</b></a></c>
为了概括起见,我保留示例中的第二句话,即
<a>This is <b>a test;</b></a>
但如果这是一个问题,则可以忽略。
答案1
这可以通过--update
将节点的值复制//c/b
到其父节点中,然后--delete
删除现在不需要的b
节点来完成。
这与我在最后采取的方法类似我之前对你的问题的回答之一,我首先创建一个内部xmlstarlet
变量,用于保存我们需要处理的所有节点的集合,然后处理这些节点。我们这样做是为了更轻松地访问同一组节点以进行更新和删除操作。在之前的回答中,这是必要的,但这里只是为了可读性。
xmlstarlet ed \
--var 'path' '//c/b' \
--update '$path/../text()[1]' --expr 'concat(., $path/text())' \
--delete '$path' file.xml
这里值得注意的是,更新并不针对b
节点的父节点,而是针对父节点的第一个文本值, text()[1]
.示例文档中节点父节点的第一个文本值//c/b
是字符串This is
。这第二文本值位于节点.
之后b
。如果我们[1]
最后选择没有,我们最终会得到
<?xml version="1.0"?>
<c>This is an example. an example<a>This is <b>a test;</b></a></c>
也就是说,该字符串an example
将被插入到c
节点的两个文本值之后。
现在,我们得到
<?xml version="1.0"?>
<c>This is an example. <a>This is <b>a test;</b></a></c>