Reputation: 361
I have hundreds of xml files to process - some have a particular desired tag, some don't. If I just add the tag to all files then some files get 2 tags (no surprises there!). How do I do it in xmlstarlet without a clumsy grep to select the files to work on? eg:
I have this in some files: ...
<parent_tag>
<another_tag/> <-- but not in all files
</parent_tag>
I want this (but some files already have it): ...
<parent_tag>
<good_tag>foobar</good_tag>
<another_tag/>
</parent_tag>
eg this works but I wish I could do it entirely in xmlstarlet without the grep:
grep -L good_tag */config.xml | while read i; do
xmlstarlet ed -P -S -s //parent_tag -t elem -n good_tag -v "" $i > tmp || break
\cp tmp $i
done
I got myself tangled up in some XPATH exoticism like:
xmlstarlet sel --text --template --match //parent_tag --match "//parent_tag/node()[not(self::good_tag)]" -f --nl */config.xml
... but it's not doing what I had hoped ...
Upvotes: 0
Views: 483
Reputation: 38672
Just select only <parent_tag/>
elements which do not contain a <good_tag/>
for inserting:
xmlstarlet ed -P -S -s '//parent_tag[not(good_tag)]' -t elem -n good_tag -v ""
If you also want to test for the right contents of the tag:
xmlstarlet ed -P -S -s '//parent_tag[not(good_tag[.="foobar"])]' -t elem -n good_tag -v ""
Upvotes: 1