【问题标题】:how to update the xml file using xmlstarlet如何使用 xmlstarlet 更新 xml 文件
【发布时间】:2023-03-23 04:35:01
【问题描述】:

我正在使用 windows 版本的 xmlstarlet 通过 windows 批处理文件更新 xml 文件。

xml edit --update "/xml/table/rec[@id=3]/@id" --value 10 %xmlfile%

我希望这会将 rec 节点的 id 属性更新为 10。当我运行它时,我会在命令行中看到更新后的 xml,但文件永远不会更新。

我该怎么做,我不想重写整个文件,因为文件可能很大。

更新前:

<?xml version="1.0"?>
<xml>
  <table>
    <rec id="1" />
    <rec id="2" />
    <rec id="3" />
  </table>
</xml>

更新后:

<?xml version="1.0"?>
<xml>
  <table>
    <rec id="1" />
    <rec id="2" />
    <rec id="10" />
  </table>
</xml>

【问题讨论】:

  • 大多数shell工具不支持就地更新数据。例如sed -i(就地)选项仍在将数据写入磁盘上的新位置,然后删除旧文件。我认为 XML 工具也是如此。如果xmlstarlet 的工作方式有所不同,我会感到非常惊讶。祝你好运。
  • 请显示更新前后的 XML 文档。
  • @Mathias 原则上我当然同意你的观点,即显示输入是好的,但这里的问题是就地编辑。 &lt;xml&gt;&lt;table&gt;&lt;rec id="3"/&gt;&lt;/table&gt;&lt;/xml&gt; 文件足以重现该问题 - id 属性已修改,但输出将打印到标准输出,而不是返回到文件。
  • @TomFenech 我也同意你的观点,但有时 OP 并没有提供可靠或完整的信息来说明发生了什么——例如,XML 文档可能格式不正确,但他们没有提到.

标签: xml bash xmlstarlet


【解决方案1】:

您没有显示您的输入文档,但我认为它是以下内容,取自xmlstarlet documentation

<xml>
  <table>
    <rec id="1">
      <numField>123</numField>
      <stringField>String Value</stringField>
    </rec>
    <rec id="2">
      <numField>346</numField>
      <stringField>Text Value</stringField>
    </rec>
    <rec id="3">
      <numField>-23</numField>
      <stringField>stringValue</stringField>
    </rec>
  </table>
</xml>

xmlstarlet 修改文件,但结果被发送到标准输出,而不是保存在原始文件中。使用另一个选项--inplace 来修改文件:

$ xml ed --inplace -u "/xml/table/rec[@id='3']/@id" -v 5 rec.xml

然后:

$ cat rec.xml
<?xml version="1.0"?>
<xml>
  <table>
    <rec id="1">
      <numField>123</numField>
      <stringField>String Value</stringField>
    </rec>
    <rec id="2">
      <numField>346</numField>
      <stringField>Text Value</stringField>
    </rec>
    <rec id="5">
      <numField>-23</numField>
      <stringField>stringValue</stringField>
    </rec>
  </table>
</xml>

顺便说一句,这个问题似乎问的问题与this question非常相似。


编辑:正如@npostavs 所建议的,此选项列在编辑帮助中:

$ xml edit --help
...
-L (or --inplace)   - edit file inplace
...

【讨论】:

  • 非常感谢,马蒂亚斯。那成功了。我一直在寻找这个选项,但在任何地方的 api 中都找不到。你是怎么找到这个的?
  • @Schu 在我看来,这确实不是文档的一部分。 Noam Postavsky briefly mentions it did not ship with the intial release.
  • 小心命名空间。我在我的文件中定义了一个命名空间,并且必须在 1.3. A More Convenient Solution 部分中的每个元素之前添加 defined in the docs _:
  • @LeoLozes 是的,如果您的文档中有命名空间,您必须处理好它们。但是问题中的文档没有命名空间,所以没有必要。
  • 谢谢.. xmlstarlet 的这个就地选项对我有很大帮助。
猜你喜欢
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
相关资源
最近更新 更多