0

I have a XML file for which transformation rules should be applied for certain elements only based on its attribute value and the rest should be retained as it is.

<bigdata>
<data>
    <Object class="QWE" Name="Country-1/State-1/QWE-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
    <Object class="RTY" Name="Country-1/State-1/RTY-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
    <Object class="UIO" Name="Country-1/State-1/UIO-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
    <Object class="PAS" Name="Country-1/State-1/PAS-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
</data>

The above xml should be converted to below xml snippet where only xml element Object for which class equals QWE should be changed to POST. ie only first element in must be changed based on its attribute. Any advices on this would be gratefull

    <bigdata>
<data>
    <Object class="POST" Name="Country-1/State-1/POST-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
    <Object class="RTY" Name="Country-1/State-1/RTY-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
    <Object class="UIO" Name="Country-1/State-1/UIO-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
    <Object class="PAS" Name="Country-1/State-1/PAS-1">
        <p name="Map">20</p>
        <p name="Required">0</p>
        <p name="Combined">68</p>
        <p name="State">0</p>
    </Object>
</data>

user1529282
  • 109
  • 1
  • 10

2 Answers2

1

Try this:

<?xml version="1.0"?>
<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.0">

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

    <xsl:template match="Object/@class[. = 'QWE' ]">
            <xsl:attribute name="class">
                <xsl:value-of select="'POST'"/>
            </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

Which will generate the following output:

<bigdata>
        <data>
                <Object class="POST" Name="Country-1/State-1/QWE-1">
                        <p name="Map">20</p>
                        <p name="Required">0</p>
                        <p name="Combined">68</p>
                        <p name="State">0</p>
                </Object>
                <Object class="RTY" Name="Country-1/State-1/RTY-1">
                        <p name="Map">20</p>
                        <p name="Required">0</p>
                        <p name="Combined">68</p>
                        <p name="State">0</p>
                </Object>
                <Object class="UIO" Name="Country-1/State-1/UIO-1">
                        <p name="Map">20</p>
                        <p name="Required">0</p>
                        <p name="Combined">68</p>
                        <p name="State">0</p>
                </Object>
                <Object class="PAS" Name="Country-1/State-1/PAS-1">
                        <p name="Map">20</p>
                        <p name="Required">0</p>
                        <p name="Combined">68</p>
                        <p name="State">0</p>
                </Object>
        </data>
</bigdata>

Update if the class value should be start with a string (QWE) and only this part should be replaced. Try this:

<xsl:template match="Object/@class[starts-with(., 'QWE') ]">
    <xsl:attribute name="class">
        <xsl:value-of select="'POST'"/>
        <xsl:value-of select="substring-after(.,'QWE')"/>
    </xsl:attribute>
</xsl:template>
hr_117
  • 9,589
  • 1
  • 18
  • 23
  • What should be done if class="QWE-1" and i should be retaining the "-1" above. New value would be class="POST-1" – user1529282 May 07 '13 at 18:32
0

Use following XSLT to transform above xml:

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@class[parent::Object]">
    <xsl:choose>
      <xsl:when test=".='QWE'">
        <xsl:attribute name="class">
          <xsl:value-of select="'POST'"/>
        </xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name="class">
          <xsl:value-of select="."/>
        </xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>

refer this for more info:

XSLT: How to change an attribute value during <xsl:copy>?

Community
  • 1
  • 1
Madurika Welivita
  • 890
  • 1
  • 10
  • 19
  • What should be done if class="QWE-1" and i should be retaining the "-1" above. New value would be class="POST-1" – user1529282 May 07 '13 at 18:45