Search code examples
xmlxsltparent-node

How can I change an attribute in a parent node?


This is the XML block:

<Object type="proto">
    <Name value="test1"/>
    <Enabled value="1"/>
    <System value="active"/>
    <Time value="10"/>
</Object>
<Object type="proto">
    <Name value="test2"/>
    <Enabled value="1"/>
    <System value="active"/>
    <Time value="20"/>
</Object>

How do I change the value of 'Time' only for 'test1' during a copy?


Solution

  • This is one possible way :

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    >
        <xsl:output method="xml" indent="yes"/>
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="Object[Name/@value='test1']/Time">
          <xsl:copy>
            <xsl:attribute name="value">30</xsl:attribute>
          </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    Brief explanation regarding xsl:templates being used :

    • <xsl:template match="@* | node()">... : Identity template; copies nodes and attributes to the output XML, unchanged.
    • <xsl:template match="Object[Name/@value='test1']/Time">... : Overrides identity template for <Time> element, that is direct child of <Object> having child Name/@value equals test1. This template copies the matched <Time> element and change the attribute value to 30.