我想說
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/trip
節點的第一傳人之前car_id
,並
-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傳遞給後者。
你已經嘗試過什麼,失敗的部分或未完成的行爲是什麼? – NeronLeVelu