Home > Back-end >  XSLT Replacing text value of the tag in 1 xml with another xml after checking if attribute are the s
XSLT Replacing text value of the tag in 1 xml with another xml after checking if attribute are the s

Time:12-21

Im beginner in this and i want to use xslt to tranform my xml file, but i'm lacking in knowledge and experience to do it. Here is an example of the file1.xml i want to transform with xsl

file1.xml

<shop>
    <SHOPITEM>
        <CATEGORY id="12306">ABCclothes</CATEGORY>
    </SHOPITEM>
    <SHOPITEM>
        <CATEGORY id="1233">SDFclothes</CATEGORY>
    </SHOPITEM>
    <SHOPITEM>
        <CATEGORY id="12308">CDFclothes</CATEGORY>
    </SHOPITEM>
</shop>

After checking if attribute id in CATEGORY is the same as id in CATEGORY2 from file2.xml, then replace element text CATEGORY from file1.xml with element text from CATEGORY2 from file2.xml

file2.xml

<ITEM>
      <CATEGORY2 id="12308">CDFreplacetext<CATEGORY2>
      <CATEGORY2 id="12306">ABCreplacetext<CATEGORY2>
</ITEM>

Here is an output i'm trying to get

Output:

<shop>
    <SHOPITEM>
        <CATEGORY id="12306">ABCreplacetext</CATEGORY> 
    </SHOPITEM>
    <SHOPITEM>
        <CATEGORY id="1233">SDFclothes</CATEGORY>
    </SHOPITEM>
    <SHOPITEM>
        <CATEGORY id="12308">CDFreplacetext</CATEGORY>
    </SHOPITEM>
</shop>

CodePudding user response:

If you can use XSLT version 3.0 (or 2.0; just replace xsl:mode with an identity transform) I'd use an xsl:key...

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:variable name="file2" select="document('file2.xml')"/>
    
    <xsl:key name="cat2" match="CATEGORY2" use="@id"/>
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:template match="CATEGORY">
        <xsl:copy>
            <xsl:apply-templates select="@*,(key('cat2',@id,$file2)/node(),node())[1]"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

If you're stuck with XSLT 1.0, try using an xsl:choose...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:variable name="file2" select="document('file2.xml')"/>
        
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="CATEGORY">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:choose>
                <xsl:when test="$file2//CATEGORY2[@id=current()/@id]">
                    <xsl:apply-templates select="$file2//CATEGORY2[@id=current()/@id]/node()"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="node()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>
  • Related