You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用xmlstarlet复制XML元素内容至Title时的重复值问题

解决XMLStarlet批量修改Product Title时重复内容的问题

问题场景

需求是将XML中每个<product>节点下的Dimensions和Size元素内容,追加到同节点的Title元素末尾。

原XML结构:

<products>
  <product>
    <id>01</id>
    <Title><![CDATA[ Product 1 Title ]]></Title>
    <Dimensions><![CDATA[ S ]]></Dimensions>
    <Size><![CDATA[ for Adult ]]></Size>
  </product>
  <product>
    <id>02</id>
    <Title><![CDATA[ Product 2 Title ]]></Title>
    <Dimensions><![CDATA[ Medium ]]></Dimensions>
    <Size><![CDATA[ for Kids ]]></Size>
  </product>
</products>

最初执行的命令:

xmlstarlet ed -u /products/product/Title -x "concat(/products/product/Title,' ',/products/product/Dimensions/text(),' ',/products/product/Size)" sourcefile.xml > outputfile.xml

出现的问题:所有产品的Title都被替换为第一个产品的拼接内容,而非对应自身的Dimensions和Size。

问题原因

原命令中的XPath使用了绝对路径(/products/product/Title),每次计算时都会选取文档中第一个匹配的节点值,导致所有Title都复用了第一个产品的内容。

解决方案

改用相对路径,基于当前被修改的Title节点来定位同层级的Dimensions和Size:

  • . 代表当前正在处理的Title节点
  • ../ 代表当前节点的父节点(即<product>),通过它可以获取同节点下的Dimensions和Size

正确的XMLStarlet命令

xmlstarlet ed -u "/products/product/Title" -x "concat(., ' ', ../Dimensions, ' ', ../Size)" sourcefile.xml > outputfile.xml

执行后得到的期望结果:

<Title><![CDATA[ Product 1 Title S for Adult]]></Title>
<Title><![CDATA[ Product 2 Title Medium for Kids]]></Title>

可选:用yq实现(v4+版本)

如果使用支持XML处理的yq v4+,也可以用以下命令实现:

yq eval '.products.product[] |= (.Title |= . + " " + .Dimensions + " " + .Size)' sourcefile.xml > outputfile.xml

内容的提问来源于stack exchange,提问作者weby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:15:29