I am very new to XSLT and no familiar at all with the logic behind. I have the following XML:
<config>
<connection port="4404" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4405" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4406" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<option>
<maxNumberOfDownloads>10</maxNumberOfDownload>
</option>
</config>
After applying some transformation from XLST - Copy XML tag and replace attribute value, I was able to copy the connection tags and change the port attribute based on the previous value.
<config>
<connection port="4404" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="7804" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4405" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="7805" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4406" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="7806" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<option>
<maxNumberOfDownloads>10</maxNumberOfDownloads>
</option>
</config>
Here is my XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- Initial template to copy all nodes and attributes -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="connection[@port]">
<xsl:copy>
<!-- Copy all nodes and attributes -->
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="port">
<xsl:value-of select="concat('78', substring(@port,3,2))"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Goal: In addition to change the port attribute, I'm trying to change the attribute enabled="false"
to the newly copied elements (connection elements that has a port that contains '78')
XML output desired:
<config>
<connection port="4404" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4405" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4406" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<option>
<maxNumberOfDownloads>10</maxNumberOfDownloads>
</option>
<connection port="7804" type="tcp">
<selection name="test-mode" enabled="false"/>
</connection>
<connection port="7805" type="tcp">
<selection name="test-mode" enabled="false"/>
</connection>
<connection port="7806" type="tcp">
<selection name="test-mode" enabled="false"/>
</connection>
</config>
Is there a way to directly update the attribute during the copy or is it necessary to create a new template ?
CodePudding user response:
It could be done in one shot.
Input XML
<config>
<connection port="4404" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4405" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="4406" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<option>
<maxNumberOfDownloads>10</maxNumberOfDownloads>
</option>
</config>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="connection[@port]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="port">
<xsl:value-of select="concat('78', substring(@port,3,2))"/>
</xsl:attribute>
<!--<xsl:apply-templates/>-->
<selection>
<xsl:apply-templates select="selection/@*"/>
<xsl:attribute name="enabled">
<xsl:value-of select="'false'"/>
</xsl:attribute>
</selection>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output
<config>
<connection port="4404" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="7804" type="tcp">
<selection name="test-mode" enabled="false"/>
</connection>
<connection port="4405" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="7805" type="tcp">
<selection name="test-mode" enabled="false"/>
</connection>
<connection port="4406" type="tcp">
<selection name="test-mode" enabled="true"/>
</connection>
<connection port="7806" type="tcp">
<selection name="test-mode" enabled="false"/>
</connection>
<option>
<maxNumberOfDownloads>10</maxNumberOfDownloads>
</option>
</config>