是否可以使用 xmlstarlet 将计算属性(即非常量)插入到 XML 文件中?
Is it possible to insert a computed attribute (i.e. non-constant) into an XML file with xmlstarlet?
我有一个这样的 XML 文件:
sources.xml
<?xml version="1.0" encoding="UTF-8"?>
<sources>
<source>
<identity id="abc"/>
<somestuff/>
</source>
<source>
<identity id="def"/>
<someotherstuff/>
</source>
</sources>
我想摆脱标签identity
并将其属性转移到父节点。换句话说,我需要将输入文件更改为:
<?xml version="1.0" encoding="UTF-8"?>
<sources>
<source id="abc">
<somestuff/>
</source>
<source id="def">
<someotherstuff/>
</source>
</sources>
我试过了:
xmlstarlet edit \
--insert "//source" --type attr --name "id" --value "identity/@id" \
--delete "//identity" \
sources.xml
这不起作用,因为 --value
将其参数理解为常量字符串。
我的问题是:xmlstarlet 是否有可能像 select
操作那样将属性 id
的值计算为 XPATH 表达式?
编辑编号。 1
我找到了朝这个方向完成某件事的方法:
xmlstarlet edit \
--insert "//source" --type attr --name "id" --value "{PLACE HOLDER}" \
--update "//source/@id" --expr "../identity/@id" \
--delete "//identity" \
sources.xml
但我得到属性 id
:
的空值
<?xml version="1.0" encoding="UTF-8"?>
<sources>
<source id="">
<somestuff>Hello</somestuff>
</source>
<source id="">
<someotherstuff/>
</source>
</sources>
表达式../identity/@id
有什么问题?
是的,这是可能的,这就是解决方案:
xmlstarlet edit \
--insert "//source" --type attr --name "id" \
--update "//source/@id" --expr "string(../identity/@id)" \
--delete "//identity" \
sources.xml
--insert
操作不接受 --expr
参数,只有 --value
,但 --update
可以。所以我们分两个不同的步骤来完成:首先创建一个空属性,然后用 --expr
更改它的值。
我们还需要使用 XPATH 函数 string()
将作为参数给定的文本节点转换为选项 --expr
的字符串。这在参考资料或教程中没有充分记录。
我 运行 遇到了类似的问题,但是计算属性必须从系统变量中获取。因此,在 OP 的许可下,我想我也会 post 在这里,以供将来参考。
如果
myvar="hello"
这将插入 "hello" 作为 id
属性值:
xmlstarlet edit --insert "//source" --type attr --name "id"\
--update "//source/@id" --value "$myvar" --delete "//identity" sources.xml
注意:这次我们要使用--value
,而不是--expr
。
我有一个这样的 XML 文件:
sources.xml
<?xml version="1.0" encoding="UTF-8"?>
<sources>
<source>
<identity id="abc"/>
<somestuff/>
</source>
<source>
<identity id="def"/>
<someotherstuff/>
</source>
</sources>
我想摆脱标签identity
并将其属性转移到父节点。换句话说,我需要将输入文件更改为:
<?xml version="1.0" encoding="UTF-8"?>
<sources>
<source id="abc">
<somestuff/>
</source>
<source id="def">
<someotherstuff/>
</source>
</sources>
我试过了:
xmlstarlet edit \
--insert "//source" --type attr --name "id" --value "identity/@id" \
--delete "//identity" \
sources.xml
这不起作用,因为 --value
将其参数理解为常量字符串。
我的问题是:xmlstarlet 是否有可能像 select
操作那样将属性 id
的值计算为 XPATH 表达式?
编辑编号。 1
我找到了朝这个方向完成某件事的方法:
xmlstarlet edit \
--insert "//source" --type attr --name "id" --value "{PLACE HOLDER}" \
--update "//source/@id" --expr "../identity/@id" \
--delete "//identity" \
sources.xml
但我得到属性 id
:
<?xml version="1.0" encoding="UTF-8"?>
<sources>
<source id="">
<somestuff>Hello</somestuff>
</source>
<source id="">
<someotherstuff/>
</source>
</sources>
表达式../identity/@id
有什么问题?
是的,这是可能的,这就是解决方案:
xmlstarlet edit \
--insert "//source" --type attr --name "id" \
--update "//source/@id" --expr "string(../identity/@id)" \
--delete "//identity" \
sources.xml
--insert
操作不接受 --expr
参数,只有 --value
,但 --update
可以。所以我们分两个不同的步骤来完成:首先创建一个空属性,然后用 --expr
更改它的值。
我们还需要使用 XPATH 函数 string()
将作为参数给定的文本节点转换为选项 --expr
的字符串。这在参考资料或教程中没有充分记录。
我 运行 遇到了类似的问题,但是计算属性必须从系统变量中获取。因此,在 OP 的许可下,我想我也会 post 在这里,以供将来参考。
如果
myvar="hello"
这将插入 "hello" 作为 id
属性值:
xmlstarlet edit --insert "//source" --type attr --name "id"\
--update "//source/@id" --value "$myvar" --delete "//identity" sources.xml
注意:这次我们要使用--value
,而不是--expr
。