I have to add an attribute on a specific element after a match, and also change the text of another element, I don't understand how I can move between elements after the match and I need some help.
I have this XML as input:
<start>
<transfers>
<transfer position="E2">
<branch name="2025_1ZTE">
<code>DKU</code>
<place>office</place>
</branch>
</transfer>
<transfer position="E3">
<branch name="1522_5MCO">
<code>TSM</code>
<place>office</place>
</branch>
</transfer>
<transfer position="E4">
<branch name="4852_3MCO">
<code>WTD</code>
<place>factory</place>
</branch>
</transfer>
</transfers>
</start>
When I match the place office and the last 3 characters of the attribute name is MCO, I need to copy all the node and add a new atributte in the element branch, and change office by teleworking, my xslt already match what I want but it add the attribute into the wrong element, because it add the attribute in transfer and not branch, and also I try to change the text of the element place but It does not change.
If the node does not match, I just need to copy it.
I need an output like :
<start>
<transfers>
<transfer position="E2">
<branch name="2025_1ZTE">
<code>DKU</code>
<place>office</place>
</branch>
</transfer>
<transfer position="E3">
<branch name="1522_5MCO" agreed="yes">
<code>TSM</code>
<place>teleworking</place>
</branch>
</transfer>
<transfer position="E4">
<branch name="4852_3MCO">
<code>WTD</code>
<place>factory</place>
</branch>
</transfer>
</transfers>
</start>
This is the XSLT that I have :
<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="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="transfer[branch[place/text()='office'][@name[substring(., string-length(.) - 2) ='MCO']]]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="agreed">yes</xsl:attribute>
<xsl:param name="place" select="'teleworking'"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
thanks
CodePudding user response:
How about simply:
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="branch[place='office' and substring(@name, string-length(@name) - 2) ='MCO']">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="agreed">yes</xsl:attribute>
<xsl:copy-of select="code"/>
<place>teleworking</place>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>