Reputation: 807
I need to copy via XSLT 1.0 g, h from //element/part[1] to //element/part[2], but I need to stick it and copy after a given element 'f'. I have this XML:
<root>
<element>
<part>
<a>1</a>
<b>2</b>
<c>3</c>
<f>4</f>
<g>5</g>
<h>6</h>
<z>50</z>
</part>
</element>
<element>
<part>
<a>1</a>
<b>2</b>
<c>3</c>
<f>4</f>
<z>55</z>
</part>
</element>
And I need to copy g, h from //element/part[1] to //element/part[2] - but I would need to copy it based on name elements, because XML is dynamic and could contain d, e before f so I can't stick it via index position. So how should I achieve this XML
<root>
<element>
<part>
<a>1</a>
<b>2</b>
<c>3</c>
<f>4</f>
<g>5</g>
<h>6</h>
<z>50</z>
</part>
</element>
<element>
<part>
<a>1</a>
<b>2</b>
<c>3</c>
<f>4</f>
<g>5</g>
<h>6</h>
<z>55</z>
</part>
</element>
I have this xsl file but it copies it at the end after 'z'
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="no" indent="yes"/>
<!-- copy everything into the output -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//root/element[2]/part">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:if test="not(g)">
<xsl:copy-of select="../../element[1]/part/g"/>
</xsl:if>
<xsl:if test="not(h)">
<xsl:copy-of select="../../element[1]/part/h"/>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 1500
Reputation: 116957
If element f
will alway be present in element[2]/part
then you could do:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="element[2]/part/f">
<xsl:copy-of select="."/>
<xsl:if test="not(../g)">
<xsl:copy-of select="../../../element[1]/part/g"/>
</xsl:if>
<xsl:if test="not(../h)">
<xsl:copy-of select="../../../element[1]/part/h"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1