简体   繁体   中英

Change value of a xml field based on condition using xslt

I need to change value of a field in xml based on some condition using xslt.

My input xml:

<?xml version="1.0" encoding="UTF-8"?>
<rows>
    <item>
        <Name>ABC</Name>
        <ID>1234</ID>
    </item>
    <item>
        <Name>XYX</Name>
        <ID>234</ID>
    </item>
    <item>
        <Name>PXC</Name>
        <ID>456</ID>
    </item> 
</rows>

My XSL code:

<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="ID" select="/rows/item/ID"/>
    <xsl:template match="/rows/item/ID">
        <xsl:choose>
            <xsl:when test="$ID = '1234'">1001</xsl:when>
            <xsl:when test="$ID = '234'">1002</xsl:when>
            <xsl:when test="$ID = '456'">1003</xsl:when>
            <xsl:when test="$ID = '789'">1004</xsl:when>
            <xsl:when test="$ID = '1903'">1005</xsl:when>
            <xsl:otherwise>
                <xsl:message terminate="no">SEVERE: No ID Mapping is found <xsl:value-of select="$ID"/>
                </xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Output xml:

<rows>
    <item>
        <Name>ABC</Name>
        1001
    </item>
    <item>
        <Name>XYX</Name>
        1001
    </item>
    <item>
        <Name>PXC</Name>
        1001
    </item> 
</rows>

i am expecting the value of ID field to change based on my choose condition. And if a value that is not maintained in the choose condition comes then it should throw error.

But the output xml is missing the xml tag for ID field and also the first choose condition value is applied to below items. Kindly help me in correcting the code.

To add the missing tags, place the contents of your template inside a xsl:copy instruction. Or change the template to match only the text node within ID .

I suspect you have another problem here, though. An XSLT variable stores a value, not an expression. In your example, the ID variable stores the value of 1001 (the first item 's ID), and it will be replicated to all item s alike - as your output shows. If you want the actual output to be determined by each ID individual value, you cannot use a global variable.

Try the following approach instead:

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="ID">
    <xsl:copy>
        <xsl:choose>
            <xsl:when test=". = '1234'">1001</xsl:when>
            <xsl:when test=". = '234'">1002</xsl:when>
            <xsl:when test=". = '456'">1003</xsl:when>
            <xsl:when test=". = '789'">1004</xsl:when>
            <xsl:when test=". = '1903'">1005</xsl:when>
            <xsl:otherwise>
                <xsl:message terminate="no">SEVERE: No ID Mapping is found <xsl:value-of select="."/></xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM