使用 xmlstarlet 更新 xml,使用一系列字母

updating xml, using xmlstarlet, with a sequence of letters

当我有 input.xml,并想更新它以获得 output.xml(见下文)XMLSTARLET 失败。

首先,我试图找到正确的 XSLT 函数来获取所需的值,结果是:

xmlstarlet sel -t -m //field -v . -o "=" -v 'substring("ABCDEFGHIJK",position(),1)' -n input.xml

输出:

 5 =A
 3 =B
 2 =C
 4 =D
 55 =E
 42 =F

这让我相信我应该能够使用以下命令更新此 XML:

xmlstarlet ed -u //field -x 'substring("ABCDEFGHIJK",position(),1)' input.xmlxmlstarlet ed -u //field -x 'substring("ABCDEFGHIJK",position(),1)' input.xml

但我确实得到了:

Invalid context position
Segmentation fault

我尝试在 Windows 11 和 Ubuntu 20.04 上使用 XmlStarlet,两者都进行了核心转储。

我对使用 XmlStarlet 的另一种解决方案感兴趣。

文件

input.xml

<root>
   <field> 5 </field>
   <field> 3 </field>
   <field> 2 </field>
   <field> 4 </field>
   <field> 55 </field>
   <field> 42 </field>
</root>

(期望)output.xml

<root>
   <field>A</field>
   <field>B</field>
   <field>C</field>
   <field>D</field>
   <field>E</field>
   <field>F</field>
</root>

position()xmlstarlet select-m (--match) 选项(即 xsl:for-each)配合使用,后者确定上下文位置。

xmlstarlet select --indent -t \
  -e '{name(*)}' \
    -m '//field' -e '{name()}' -v 'substring("ABCDEFGHIJK",position(),1)' \
file.xml

对于 xmlstarlet edit-u (--update),您可以使用兄弟节点计数,例如

xmlstarlet edit -O \
  -u '//field' -x 'substring("ABCDEFGHIJK",1+count(preceding-sibling::field),1)' \
file.xml

xmlstarlet edit -O \
  -u '//field' -x 'substring("ABCDEFGHIJK",count(preceding-sibling::* | self::*),1)' \
file.xml

这些命令中的每一个都会产生所需的输出。添加了行继续符以提高可读性。