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 thexsl
namespace declaration.You had a template to match
Property
elements whosename
attribute equalled1
, and do nothing (i.e. to remove such aProperty
), but that template was never actually invoked, because of the other template that matched theProperties
element.The template that matched the
Properties
element had achoose
child containing awhen
which would check to see if theProperties
element had aProperty
child element with aname
attribute whose value was1
, and if it did, the template would create a newProperty
element whosename
attribute was also1
, and give it the contentINFO
. Thechoose
element had no other child elements (otherwhen
orotherwise
elements) so in the case that theProperties
element did not have aProperty/@name='1'
, the template would do nothing, effectively ignoring all theProperty
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>