Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
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
 
Old October 20th, 2010, 06:30 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
Default 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?
 
Old October 20th, 2010, 06:46 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

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:
Kanini (October 20th, 2010)
 
Old October 20th, 2010, 07:04 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
Default

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.
 
Old October 20th, 2010, 09:18 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
Default How to set the value from a Variable

Additional Request. If I am passing the new values via Variables, how will I update it?
 
Old October 20th, 2010, 09:23 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

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:
Kanini (October 20th, 2010)
 
Old October 20th, 2010, 11:37 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
Default Thanks!

Martin: Thanks Very Much!
 
Old October 21st, 2010, 05:35 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
Default



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)

 
Old October 21st, 2010, 06:21 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

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:
Kanini (October 21st, 2010)
 
Old October 21st, 2010, 07:07 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 4
Thanked 0 Times in 0 Posts
Default


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.
 
Old October 21st, 2010, 07:20 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

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:
Kanini (October 21st, 2010)





Similar Threads
Thread Thread Starter Forum Replies Last Post
XSLT 1. 0 Grouping by two attributes and creating table Narendra.Patil XSLT 29 March 5th, 2012 10:39 AM
Modify XSLT mikeymikey XSLT 4 January 5th, 2008 11:21 PM
Modify XML with XSLT aowen355 XSLT 4 December 26th, 2007 10:19 AM
xslt grouping with attributes Jimi XSLT 4 October 31st, 2007 10:56 AM
Modify Attributes of ASF files arun.sharma.kumar Visual C++ 0 February 15th, 2007 03:27 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.