2

I want to move around elements in an xml document with xmlstarlet

Specifically I want to make the following changes

<parent> <before/> <span><a>blah</a></span> <after/> <parent> <otherparent> <span><a>blah</a></span> <otherparent> 

becomes ..

<parent> <before/> <a>blah</a> <after/> </parent> <otherparent> <a>blah</a> </otherparent> 

I.e delete span but keep the children.

xmlstarlet has a move command: xmlstart ed -m source target but I don't really understand how it works.

It takes a source and a target xpath but I don't really understand how these get matched up because they can result in sets of different sizes. Is the target relative to the source?

6
  • add more context/parent structure - it should be shown where the resulting <a>blah</a> is located/inserted. Post the structure with parent nodes Commented Oct 31, 2017 at 17:02
  • 1
    I don't feel that this is particularly relevant. I want delete all spans while keeping their content. This is really just an example to motivate the question. Commented Oct 31, 2017 at 17:06
  • you don't understand, the crucial child nodes should be moved in right places in case if spans are in arbitrary order within xml document. Commented Oct 31, 2017 at 17:08
  • Ah I understand... the problem isn't completely specified without other children. I guess I want it to "stay correct location?" Commented Oct 31, 2017 at 17:09
  • For ex. <div><span id="1"><span><a>blah</a></span></span></div><div></div><div><span id="2"><span><a>blah</a></span></span></div> Commented Oct 31, 2017 at 17:11

1 Answer 1

1

Complex xmlstarlet solution:

Input xml file test.xml:

<div> <parent> <before/> <span> <a>value 1</a> </span> <after/> </parent> <otherparent> <span> <a>value 2</a> </span> </otherparent> </div> 

The job:

count=$(xmlstarlet sel -t -v 'count(//span[a])' test.xml) for ((i=1; i<=$count; i++)); do xmlstarlet ed -L -a '(//span[a])[1]' -t elem -n "a" -v "$(xmlstarlet sel -t -v "(//span/a)[1]" 1.xml)" -d '(//span[a])[1]' test.xml done 

  • count - variable containing the number of span nodes which have child a node

  • ed - edit mode

  • -L - modify the file inplace

  • -a - append action

  • -d - delete action


The final test.xml (after processing):

<?xml version="1.0"?> <div> <parent> <before/> <a>value 1</a> <after/> </parent> <otherparent> <a>value 2</a> </otherparent> </div> 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.