I have an xml file of the following form:
<results>
<sequence-name>name1</sequence-name>
<repetitions>
<window>
<key1>1</key1>
</window>
</repetitions>
<sequence-name>name2</sequence-name>
<repetitions>
<window>
<key1>4</key1>
</window>
</repetitions>
</results>
I would like to move the element sequence-name
such that it is the first element inside window
, so the output should look like:
<results>
<repetitions>
<window>
<sequence-name>name1</sequence-name>
<key1>1</key1>
</window>
</repetitions>
<repetitions>
<window>
<sequence-name>name2</sequence-name>
<key1>4</key1>
</window>
</repetitions>
</results>
I tried using grep to produce two files, one containing just the lines with <sequence-name>
, and one with all the other lines. But I can't figure out how to insert the lines containing <sequence-name>
back into the place I would like. I'm guessing there is a solution using sed/aw
k. I am also happy to use a tool such as xmlstarlet
.
The following stylesheet should do the trick:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/ | node()">
<xsl:copy>
<xsl:apply-templates select="node()[not(self::sequence-name)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="window">
<xsl:copy>
<xsl:copy-of select="preceding::sequence-name[1]" />
<xsl:apply-templates select="key1"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You can apply it using xsltproc stylesheet data
or xmlstarlet tr stylesheet data
.