更改XML结构

时间:2015-06-11 12:39:20

标签: replace sed grep xmlstarlet

您好我需要对xml的这一部分进行一些文本操作。 删除一些标签没问题。我需要在将汽车ID重命名为CAR_ID并移入TRIP标签之前。

ie:MLStarlet Toolkit?

xmlstarlet somevariable

原始

  <car>
    <id>155028827</id>
    <trip>
      <id>1</id>
      <date>1.1.1970</date>
    </trip>
    <trip>
      <id>2</id>
      <date>1.1.1970</date>
    </trip>
  </car>

预期结果

<trip>
  <car_id>155028827</id>
  <id>1</id>
  <date>1.1.1970</date>
</trip>
<trip>
  <car_id>155028827</id>
  <id>2</id>
  <date>1.1.1970</date>
</trip>

1 个答案:

答案 0 :(得分:1)

我会说

xmlstarlet ed -i '/car/trip/descendant::node()[1]' -t elem -n car_id -u '/car/trip/car_id' -x 'ancestor::node()["car"]/id/text()' filename.xml | xmlstarlet sel -t -c '/car/trip'

这分为两部分:

xmlstarlet ed \
   -i '/car/trip/descendant::node()[1]' -t elem -n car_id \
   -u '/car/trip/car_id' -x 'ancestor::node()["car"]/id/text()' \
   filename.xml

xmlstarlet sel -t -c '/car/trip'

第一个是xmlstarlet ed命令,这意味着XML进入,编辑和编辑XML。编辑是

   -i '/car/trip/descendant::node()[1]' -t elem -n car_id

在每个car_id节点的第一个后代之前插入/car/trip,并且

   -u '/car/trip/car_id' -x 'ancestor::node()["car"]/id/text()'

将所有/car/trip/car_id个节点的值设置为其id祖先节点的car子节点内的文本。仅这一点就产生了

<?xml version="1.0"?>
<car>
  <id>155028827</id>
  <trip>
    <car_id>1550288271</car_id>
    <id>1</id>
    <date>1.1.1970</date>
  </trip>
  <trip>
    <car_id>1550288272</car_id>
    <id>2</id>
    <date>1.1.1970</date>
  </trip>
</car>

然后通过管道传输

xmlstarlet sel -t -c '/car/trip'

这将选择(并打印)此XML数据的/car/trip个节点,生成

<trip>
    <car_id>1550288271</car_id>
    <id>1</id>
    <date>1.1.1970</date>
  </trip><trip>
    <car_id>1550288272</car_id>
    <id>2</id>
    <date>1.1.1970</date>
  </trip>

如果格式化了你,你可以使用

xmlstarlet sel -t -c '/car/trip | /car/text()'

保留标记之间的空格(并获得更可读的格式化输出);通过此更改,输出

  <trip>
    <car_id>1550288271</car_id>
    <id>1</id>
    <date>1.1.1970</date>
  </trip>
  <trip>
    <car_id>1550288272</car_id>
    <id>2</id>
    <date>1.1.1970</date>
  </trip>

......顶部还有两条空行;它们是/car/id节点之前和之后的换行符。不幸的是,输出数据不再是有效的XML,所以我们不能只通过XML漂亮的打印机(这是我真正想做的)。由于我怀疑这将嵌入更多的XML(以便可以正确解析),如果格式化很重要,我的建议是先嵌入这个,然后通过漂亮的打印机管理整个XML。 / p>