Home > Software design >  In XML using XSLT, Copy few elements and change value of others
In XML using XSLT, Copy few elements and change value of others

Time:10-20

I have a xml file like this

<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="abc">
    <Properties>
        <Property name="1">A</Property>
        <Property name="2">B</Property>
        <Property name="3">C</Property>
        <Property name="4">D</Property>
        <Property name="5">E</Property>
        <Property name="6">F</Property>
    </Properties>
</Configuration>

I want to change the value of property names 1 and 2 only and for others to stay as it is.

Here is the code which I am using, but it is removing all other element and giving me value of only 1 element in my output file,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Configuration/Properties/Property[@name='1']" />
        <xsl:template match="Configuration/Properties">
        <xsl:element name="Properties">
            <xsl:choose>
                <xsl:when test="(Property/@name='1')">
                <xsl:element name="Property" >
                    <xsl:attribute name="name">
                    <xsl:value-of select="'1'"/>
                    </xsl:attribute>
                    <xsl:value-of select="'INFO'"/>
                </xsl:element>
                </xsl:when>
            </xsl:choose>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Thank you.

CodePudding user response:

There were quite a few things wrong with your stylesheet.

  • Firstly, it was not well-formed XML; it was missing a closing > on the stylesheet element, and also the xsl namespace declaration.

  • You had a template to match Property elements whose name attribute equalled 1, and do nothing (i.e. to remove such a Property), but that template was never actually invoked, because of the other template that matched the Properties element.

  • The template that matched the Properties element had a choose child containing a when which would check to see if the Properties element had a Property child element with a name attribute whose value was 1, and if it did, the template would create a new Property element whose name attribute was also 1, and give it the content INFO. The choose element had no other child elements (other when or otherwise elements) so in the case that the Properties element did not have a Property/@name='1', the template would do nothing, effectively ignoring all the Property child elements.

I suspect you have some misconceptions about the way XSLT works and I'd recommend some background reading to get a more solid understanding.

My example shows a simple way to replace the text values.

I've retained your identity template which has the effect of copying everything which isn't matched by a more specific template. Then I added a template to match the text node inside the Property element whose name attribute was 1. That text node is of course the node containing the value A. The template then outputs a new text node INFO. Note that if this template did not exist, the identity template would have matched that text node (A), instead, and would have copied it.

<xsl:stylesheet version="2.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="
        Configuration/Properties/Property[@name='1']/text()
    ">INFO</xsl:template>

</xsl:stylesheet>

CodePudding user response:

I don't think that you need to define all of these. Just copy whole and update those particular values.

<xsl:template match="Configuration/Properties/Property[@name='1']/text()">'Your value'</xsl:template>
<xsl:template match="Configuration/Properties/Property[@name='2']/text()">'Your 2nd value'</xsl:template>
  • Related