Replace 更改XML结构
嗨,我需要对这部分xml进行一些文本操作。 删除一些标记没有问题。在此之前,我需要将车号重命名为car_ID,并移动到行程标签内 ie:MLStarlet工具包 xmlstarlet变量 原创的Replace 更改XML结构,replace,sed,grep,xmlstarlet,Replace,Sed,Grep,Xmlstarlet,嗨,我需要对这部分xml进行一些文本操作。 删除一些标记没有问题。在此之前,我需要将车号重命名为car_ID,并移动到行程标签内 ie:MLStarlet工具包 xmlstarlet变量 原创的 <car> <id>155028827</id> <trip> <id>1</id> <date>1.1.1970</date> </trip>
<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>
155028827
1.
1.1.1970
2.
1.1.1970
期望结果
<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>
155028827
1.
1.1.1970
155028827
2.
1.1.1970
我想说
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 ed
命令,这意味着XML进入、编辑,编辑后的XML退出。编辑是
-i '/car/trip/descendant::node()[1]' -t elem -n car_id
在每个/car/trip
节点的第一个子节点之前插入car\u id
,以及
-u '/car/trip/car_id' -x 'ancestor::node()["car"]/id/text()'
它将所有/car/trip/car\u id
节点的值设置为其car
祖先节点的id
子节点内的文本。仅此一点就产生了
<?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>
这将选择(并打印)此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>
保留标记之间的空白(并获得更易于阅读的格式化输出);通过此更改,输出是
<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>
1550288271
1.
1.1.1970
1550288272
2.
1.1.1970
…顶部还有两行空白;它们是
/car/id
节点前后的换行符。不幸的是,输出数据不再是有效的XML,因此我们不能通过XML漂亮的打印机(这正是我真正想做的)。由于我怀疑这将被嵌入到进一步的XML中(以便正确解析),因此,如果格式化很重要,我的建议是先嵌入这一点,然后通过漂亮的打印机将整个XML传输。您已经尝试了什么,失败的部分或未解决的行为是什么?您是最好的。thx很多,我不是程序员,“后代::节点()[1]”对我来说就像来自火星的音乐:)。非xml标准没有问题,我将准备xml以插入mysql。再次使用Thx。这些过滤器是表达式<代码>子体是一个。XPath在处理XML时是一个非常方便的工具(学习起来并不困难),因此我鼓励您仔细阅读。您可以使用--root
或-R
(如xmlstarlet sel-R-t…
)将输出打包到单个节点中。
<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>