 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

October 20th, 2010, 06:30 AM
|
|
Registered User
|
|
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
Modify Attributes using XSLT
Hello...I have an XML file as follows
Code:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<Environments>
<Environment id="Master" description="MasterSystem">
<Systems>
<DefaultSystem systemName="Master" server="http://localhost" />
</Systems>
</Environment>
<Environment id="DeveloperA" description="DeveloperASystem">
<Systems>
<DefaultSystem systemName="DeveloperA" server="http://DevAMachine" />
</Systems>
</Environment>
<Environment id="DeveloperB" description="DeveloperBSystem">
<Systems>
<DefaultSystem systemName="DeveloperB" server="http://DevBMachine" />
</Systems>
</Environment>
</Environments>
</Configuration>
What I would want to do is:
Modify the Environment which has id="DeveloperB" as follows
id: DeveloperC
description: DeveloperCSystem
systemName: DeveloperC
How do I do it with XSLT?
|
|

October 20th, 2010, 06:46 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Code:
<xsl:tempate match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:tempate>
<xsl:template match="Environment/@id[. = 'DeveloperB']">
<xsl:attribute name="id">DeveloperC</xsl:attribute>
</xsl:template>
<xsl:template match="Environment[@id = 'DeveloperB']/@description">
<xsl:attribute name="description">DeveloperCSystem</xsl:attribute>
</xsl:template>
<xsl:template match="Environment[@id = 'DeveloperB']/Systems/DefaultSystem/@systemName">
<xsl:attribute name="systemName">DeveloperC</xsl:attribute>
</xsl:template>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

October 20th, 2010, 07:04 AM
|
|
Registered User
|
|
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
Martin: Thanks! However, a small typo-correction. In the first Transformation where you copy all of the Elements, your code read as tempate (without an l).
For others, who may find it beneficial, the below is the complete working code.
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Environment/@id[. = 'DeveloperB']">
<xsl:attribute name="id">DeveloperC</xsl:attribute>
</xsl:template>
<xsl:template match="Environment[@id = 'DeveloperB']/@description">
<xsl:attribute name="description">DeveloperCSystem</xsl:attribute>
</xsl:template>
<xsl:template match="Environment[@id = 'DeveloperB']/Systems/DefaultSystem/@systemName">
<xsl:attribute name="systemName">DeveloperC</xsl:attribute>
</xsl:template>
</xsl:transform>
Last edited by Kanini; October 20th, 2010 at 07:05 AM..
Reason: Added closing xsl:transform code.
|
|

October 20th, 2010, 09:18 AM
|
|
Registered User
|
|
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
How to set the value from a Variable
Additional Request. If I am passing the new values via Variables, how will I update it?
|
|

October 20th, 2010, 09:23 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Code:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="new-name" select="'DeveloperC'"/>
<xsl:param name="new-desc" select="'DeveloperCSystem'"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Environment/@id[. = 'DeveloperB']">
<xsl:attribute name="id">DeveloperC</xsl:attribute>
</xsl:template>
<xsl:template match="Environment[@id = 'DeveloperB']/@description">
<xsl:attribute name="description"><xsl:value-of select="$new-desc"/></xsl:attribute>
</xsl:template>
<xsl:template match="Environment[@id = 'DeveloperB']/Systems/DefaultSystem/@systemName">
<xsl:attribute name="systemName"><xsl:value-of select="$new-name"/></xsl:attribute>
</xsl:template>
</xsl:transform>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

October 20th, 2010, 11:37 AM
|
|
Registered User
|
|
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
Thanks!
Martin: Thanks Very Much!
|
|

October 21st, 2010, 05:35 AM
|
|
Registered User
|
|
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
If the matching has to be done based on a a variable?
Code:
<xsl:template match="Environment/@id[. ='$SelectEnvironment']">
<xsl:attribute name="id">
<xsl:value-of select="$EnvironmentId"/>
</xsl:attribute>
</xsl:template>
The above code will not work because, I cannot use variables in <xsl:template>
So, how would I select a particular root element based on a attribute value, change it's attribute values, select a child element based on an attribute value and change it's attribute values?
That is, for the same XML
Code:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<Environments>
<Environment id="Master" description="MasterSystem">
<Systems>
<DefaultSystem systemName="Master" server="http://localhost" />
</Systems>
</Environment>
<Environment id="DeveloperA" description="DeveloperASystem">
<Systems>
<DefaultSystem systemName="DeveloperA" server="http://DevAMachine" />
</Systems>
</Environment>
<Environment id="DeveloperB" description="DeveloperBSystem">
<Systems>
<DefaultSystem systemName="DeveloperB" server="http://DevBMachine" />
</Systems>
</Environment>
</Environments>
</Configuration>
I want to be able to choose element Environment which has id value = "DeveloperB" (passed via a variable), update the value of id and description (passed via variables) and choose the child element DefaultSystem and update the systemName attribute with a value (passed via a variable)
|
|

October 21st, 2010, 06:21 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Consider to switch to XSLT 2.0 and an XSLT 2.0 processor like Saxon 9 ( http://saxon.sourceforge.net/) or AltovaXML Tools ( http://www.altova.com/altovaxml.html), that way you are allowed to use variables or parameter references (i.e. $var) in match patterns of a template element.
That is my primary suggestion. Let us know whether that is possible for you.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

October 21st, 2010, 07:07 AM
|
|
Registered User
|
|
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
Martin: Thanks! I will take a look at them. However, out of a learning enquiry, is it not possible to do this sort of a check attr value and update (element and its child) at all or is it just too complicated?
I would prefer not to use third-party processors as such and would prefer to get it accomplished via basic XSLT itself.
|
|

October 21st, 2010, 07:20 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
It is possible with XSLT 1.0 but more code and somehow convoluted code is needed, along these lines
Code:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="id-to-change" select="'DeveloperB'"/>
<xsl:param name="new-name" select="'DeveloperC'"/>
<xsl:param name="new-desc" select="'DeveloperCSystem'"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Environment/@id">
<xsl:choose>
<xsl:when test=". = $id-to-change">
<xsl:attribute name="id">
<xsl:value-of select="$new-name"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Environment/@description">
<xsl:choose>
<xsl:when test="../@id = $id-to-change">
<xsl:attribute name="description">
<xsl:value-of select="$new-desc"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Environment/Systems/DefaultSystem/@systemName">
<xsl:choose
<xsl:when test="../../../@id = $id-to-change">
<xsl:attribute name="systemName">
<xsl:value-of select="$new-name"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:transform>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|
 |