首页 > 解决方案 > 使用带有 xmlstarlet 的 XPath 表达式更新 XML

问题描述

我有一个这样的 junit 报告 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<testsuites>
    <testsuite>
        <testcase classname='Formatting Test' name='Test.swift'>
            <failure message='Function parameters should be aligned vertically'>warning: Line:39 </failure>
        </testcase>
        <testcase classname='Formatting Test' name='Test.swift'>
            <failure message='Function parameters should be aligned vertically'>warning: Line:40 </failure>
        </testcase>
    </testsuite>
</testsuites>

我想使用 XMLStarlet 将<failure>标签的内容替换为其message属性。我发现了一个关于使用 xpath 表达式更新的类似问题:SO question

但如果我尝试任何这些命令:

xmlstarlet edit -u '//testsuites/testsuite/testcase/failure' -x '@message/text()' test.xml
xmlstarlet edit -u '//testsuites/testsuite/testcase/failure' -x '@message' test.xml

然后<failure> 值完全消失了。如果我使用它(只是为了测试):

xmlstarlet edit -u '//testsuites/testsuite/testcase/failure' -x '../@name' test.xml

结果将是:

<?xml version="1.0" encoding="utf-8"?>
<testsuites>
  <testsuite>
    <testcase classname="Formatting Test" name="Test.swift">
      <failure message="Function parameters should be aligned vertically" name="Test.swift"/>
    </testcase>
    <testcase classname="Formatting Test" name="Test.swift">
      <failure message="Function parameters should be aligned vertically" name="Test.swift"/>
    </testcase>
  </testsuite>
</testsuites>

它将name属性附加到<failure>标签!xpath 如何处理-x参数非常令人困惑。那么如何将<failure>标签的内容替换为其属性值呢?

标签: xmlxpathxmlstarlet

解决方案


我认为你很接近,但你正在选择一个属性节点。这就是name在上一个命令行示例中添加该属性的原因。

要使用属性的值,请将其转换为带有string().

试试这个更新的命令行:

xmlstarlet edit -u '//testsuites/testsuite/testcase/failure' -x 'string(@message)' test.xml

注意:您也可以将您的缩写缩短-u'//failure'.


推荐阅读