您好我需要对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>
答案 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>