Copying and moving child node with XSLT



I have this xsl script that transforms an incorrect xml, thereby moving the port children to the correct parent host.



<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="host">
<xsl:variable name="hostname" select="@name"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="//host/port[@parent=$hostname]">
<xsl:sort select="@name" data-type="text" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>


Example of incorrect xml (some ports are not placed under their parent)



<hosts>
<host modelID="1" name="H2">
<port ID="H2.Port1" name="Port1" parent="H2" speed="100"/>
<port ID="H2.Port2" name="Port2" parent="H2" speed="100"/>
<port ID="H1.Port1" name="Port1" parent="H1" speed="100"/>
</host>
<host modelID="1" name="H1"/>
</hosts>


Desired output.



<hosts>
<host modelID="1" name="H2">
<port ID="H2.Port1" name="Port1" parent="H2" speed="100"/>
<port ID="H2.Port2" name="Port2" parent="H2" speed="100"/>
</host>
<host modelID="1" name="H1">
<port ID="H1.Port1" name="Port1" parent="H1" speed="100"/>
</host>
</hosts>


Now I want to change the script to include a new element: ports New desired output.



<hosts>
<host modelID="1" name="H2">
<ports>
<port ID="H2.Port1" name="Port1" parent="H2" speed="100"/>
<port ID="H2.Port2" name="Port2" parent="H2" speed="100"/>
</ports>
</host>
<host modelID="1" name="H1">
<ports>
<port ID="H1.Port1" name="Port1" parent="H1" speed="100"/>
</ports>
</host>
</hosts>


I was hoping that I would only need to change the line



<xsl:apply-templates select="//host/port[@parent=$hostname]">


to



<xsl:apply-templates select="//host/ports/port[@parent=$hostname]">


Why does this not work, and what need I do instead?


No comments:

Post a Comment