Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT: Change certain attribute values

Tags:

xml

xslt

xpath

I am a XSLT newbie and have a simple task:

Suppose I have the following XML:

<Element1>
    <Element2 attr1="1"/>
</Element1>
<Element1 attr1="2"/>
<Element1>
    <Element2 attr1="2"/>
</Element1>

I want to transform the XML to the same XML with one change: All attributes named "attr1" no matter where they are have to be transformed so that for example "1" will be "A" and "2" will be "X", i. e. to

<Element1>
    <Element2 attr1="A"/>
</Element1>
<Element1 attr1="X"/>
<Element1>
    <Element2 attr1="X"/>
</Element1>

How can I achieve this? Thanks in advance!

like image 324
Alexander Avatar asked Jul 22 '11 08:07

Alexander


2 Answers

You can define characters to replace and replacing chars, then use translate. You can use this XSLT:

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

    <xsl:variable name="in">12</xsl:variable>
    <xsl:variable name="out">AX</xsl:variable>

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

    <xsl:template match="@attr1">
        <xsl:attribute name="attr1">
            <xsl:value-of select="translate(., $in, $out)"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

Another way:

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

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

    <xsl:template match="@attr1">
        <xsl:choose>
            <xsl:when test=". = '1'">
                <xsl:attribute name="attr1">
                    <xsl:text>A</xsl:text>
                </xsl:attribute>
            </xsl:when>
            <xsl:when test=". = '2'">
                <xsl:attribute name="attr1">
                    <xsl:text>X</xsl:text>
                </xsl:attribute>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

<xsl:template match="@attr1"> will match all attributes attr1, then using xsl:choose you creates appropriate value for this attribute.

like image 60
Kirill Polishchuk Avatar answered Nov 11 '22 21:11

Kirill Polishchuk


You didn't say what happens when @attr=3 for example so there is an otherwise clause to just copy the value if it is not one of the selected.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="@attr1">
  <xsl:attribute name="attr1">
    <xsl:choose>
      <xsl:when test=". = 1">
        <xsl:text>A</xsl:text>
      </xsl:when>
      <xsl:when test=". = 2">
        <xsl:text>X</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
</xsl:template>
</xsl:stylesheet>
like image 30
Bob Vale Avatar answered Nov 11 '22 21:11

Bob Vale