xsltxslt-1.0

Updating two different nodes using XSLT


Updating two different nodes using XSLT

Input -

<root>
    <Bank>
        <BankDetail>
            <Name1>
            </Name1>
            <Name2>TestBank</Name2>
        </BankDetail>
    </Bank>
    <Item>
        <Item1>1235</Item1>
    </Item>
</root>

Existing XSLT

The XSLT is doing one task of copying the value from Name2 Tag to Name1.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" version="1.0">
    <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" version="1.0"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:variable name="varName">
        <xsl:if test="/root/Bank/BankDetail/Name1 = ''">
            <xsl:value-of select="/root/Bank/BankDetail/Name2"/2
        </xsl:if>
    </xsl:variable>
    <xsl:template match="/root/Bank/BankDetail/Name1">
            <xsl:copy>
            <xsl:value-of select="$varName"/>
            <xsl:apply-templates/>
            </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Now, another update needs to be made using the same XSLT. Replacing the <Item1> value 1235 with "Item No 1" string.

Need this in XSLT 1.0

Desired Output -

<root>
    <Bank>
        <BankDetail>
            <Name1>TestBank</Name1>
            <Name2>TestBank</Name2>
        </BankDetail>
    </Bank>
    <Item>
        <Item1>Item No 1</Item1>
    </Item>
</root>

I am new to the XSLT. Please let me know if we have any way to do the updates in same XSLT.

This is my best attempt

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" version="1.0">
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" version="1.0"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:variable name="varName">
    <xsl:if test="xml/Bank/BankDetail/Name1 = ''">
        <xsl:value-of select="xml/Bank/BankDetail/Name2"/>
    </xsl:if>
</xsl:variable>

<xsl:variable name="varItem" select="'Item No 1'"/>

<xsl:template match="xml/Bank/BankDetail/Name1">
        <xsl:copy>
        <xsl:value-of select="$varName"/>
        <xsl:apply-templates/>
        </xsl:copy>
</xsl:template>
<xsl:template match="xml/Item/Item1">
        <xsl:copy>
        <xsl:value-of select="$varItem"/>
        <xsl:apply-templates/>
        </xsl:copy>
</xsl:template></xsl:stylesheet>

The Output its giving as

<xml>
<Bank>
    <BankDetail>
        <Name1>TestBank</Name1>
        <Name2>TestBank</Name2>
    </BankDetail>
</Bank>
<Item>
    <Item1>Item No 11235</Item1>
</Item>

Not sure why this is appending with existing value rather overriding.


Solution

  • If the input is e.g.

    <root>
        <Bank>
            <BankDetail>
                <Name1>
                </Name1>
                <Name2>TestBank</Name2>
            </BankDetail>
        </Bank>
        <Item>
            <Item1>1235</Item1>
        </Item>
    </root>
    

    then I think

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
      <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" version="1.0"/>
      
      <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
      
      <xsl:variable name="varItem" select="'Item No 1'"/>
      
      <xsl:template match="root/Bank/BankDetail/Name1[not(normalize-space())]">
        <xsl:copy>
          <xsl:value-of select="/root/Bank/BankDetail/Name2"/>
        </xsl:copy>
      </xsl:template>
      
      <xsl:template match="root/Item/Item1">
        <xsl:copy>
          <xsl:value-of select="$varItem"/>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    to conditionally (if Name1 doesn't have anything more but whitespace) fill Name1 with the Name2 value and to unconditionally fill Item1 with that constant value from the variable.

    I am not sure that captures your intent as you haven't really spelled out any possible variations of input and output but I hope it gets you an idea on how to start with the identity transformation template and add further one for the node or element wise transformations/changes you want to perform.