'How to wrap child elements in a parent tag using xmlstarlet
I want to wrap "table" elements with a new parent anywhere in the xml file. Am new using xmlstarlet. Input:
<table>
</table>
<oldTable>
<table>
</table>
</oldTable>
Desired output:
<newparent id="tab">
<table>
</table>
</newparent>
<oldTable>
<newparent id="tab">
<table>
</table>
</newparent>
<oldTable>
Solution 1:[1]
Assuming a POSIX shell:
xmlstarlet edit \
--var T '//table[not(parent::newparent)]' \
-i '$T' -t 'elem' -n 'newparent' \
-a '$prev' -t 'attr' -n 'typ' -v 'wtab' \
-u '//newparent[following-sibling::*[1][self::table]]' \
-x 'following-sibling::*[1]' \
-d '$T' \
file.xml > newfile.xml
where:
--var T …collect candidatetableelements in variableT-iinsert anewparentelement before eachtable-aappend atypattribute to the element just created-uupdate allnewparentelements having an immediately followingtablesibling element
with (-xXPath expression) a deep copy of that sibling-ddelete the copied siblings
xmlstarlet edit code can use the convenience $prev (aka
$xstar:prev) node to refer to the node created by the most recent
-i (--insert), -a (--append), or -s (--subnode) option.
Examples of $prev are given in
doc/xmlstarlet.txt.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
