Search code examples
xmlxsltxslt-1.0xslt-2.0

Replace values in element in xml file using xslt


I want to remove unnecessary text inside values in elements in xml file and I want use an XSLT transformation to do that.

In this example file i want to remove specific tags like <br>, <prefix>, <suffix> inside value of <Value> elements.

There will be many <Product> elements. And I don't want change structure of this file, so this should be like copy, but with with logic to remove specific texts.

I tried to use templates and copy, but somehow I cannot connect them together.

If any of you could help me with or give me hints that I should follow, I would appreciate.

<ProductInfo>
  <Products>
    <Product>
     <Name>xyz</Name>
     <Values>
        <Value><br/>test</Value> <-- remove <br/>
        <Value><prefix/>test2</Value> <-- remove <prefix>
        <Value><suffix/>test3</Value> <-- remove <suffix/>
     </Values>
    </Product>
  <Product>
     <Name>xyz</Name>
     <Values>
        <Value><br/>test</Value> <-- remove <br/>
        <Value><prefix/>test2</Value> <-- remove <prefix/>
        <Value><suffix/>test3</Value> <-- remove <suffix/>
     </Values>
    </Product>
  </Products>
</ProductInfo>

Output file should look like:

<ProductInfo>
  <Products>
    <Product>
     <Name>xyz</Name>
     <Values>
        <Value>test</Value>
        <Value>test2</Value>
        <Value>test3</Value>
     </Values>
    </Product>
  <Product>
     <Name>xyz</Name>
     <Values>
        <Value>test</Value> 
        <Value>test2</Value> 
        <Value>test3</Value> 
     </Values>
    </Product>
  </Products>
</ProductInfo>

Solution

  • The following stylesheet:

    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="Value">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    will remove any markup contained in a Value element by returning only it string-value - i.e. "the concatenation of the string-values of all text node descendants of the element node in document order".