Reputation: 11
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.
Upvotes: 0
Views: 307
Reputation: 3258
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>
Upvotes: 1
Reputation: 36
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>
Upvotes: 0