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 December 21st, 2005, 09:08 AM
Registered User
 
Join Date: Dec 2005
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default Increment a tag

Hello all,

I am new in xml and xslt world so, I am sorry to post you maybe a very stupid question

I have the following structure in my xml:
<START_A>
      <HEADER OPERATION="Import" PRIMARY="Data1">
                  <tutu type="S">Myname</tutu>
                  <tyty type="S">Hisname</tyty>
      </HEADER>
       <START_B>
           <HisTag>
                <tata type='S'>TTTTTTT</tata>
                <tete type='S'>DDDDDD</tete>
           </HisTag>
           <MyTag>
                <toto type='S'>AA</toto>
                <titi type='I'>9.000</titi>
           </MyTag>
           <MyTag>
                <toto type='S'>BB</toto>
                <titi type='I'>3.000</titi>
           </MyTag>
           <MyTag>
                <toto type='S'>CC</toto>
                <titi type='I'>10.000</titi>
           </MyTag>
      </START_B>
</START_A>

and I need to transform that into:

<START_A>
      <HEADER OPERATION="Import" PRIMARY="Data1">
                  <tutu type="S">Myname</tutu>
                  <tyty type="S">Hisname</tyty>
      </HEADER>
       <START_B>
           <HisTag>
                <tata type='S'>TTTTTTT</tata>
                <tete type='S'>DDDDDD</tete>
           </HisTag>
           <MyTag1>
                <toto type='S'>AA</toto>
                <titi type='I'>9.000</titi>
           </MyTag1>
           <MyTag2>
                <toto type='S'>BB</toto>
                <titi type='I'>3.000</titi>
           </MyTag2>
           <MyTag3>
                <toto type='S'>CC</toto>
                <titi type='I'>10.000</titi>
           </MyTag3>
      </START_B>
</START_A>

The aim is just to add an increment number on MyTag.

Is there a simple way to do that with xslt? or another way to do it ?

Thank you in advance for your help.
Regards.
Stefan

 
Old December 21st, 2005, 09:50 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

It's a peculiar thing to want to do, because tag names are supposed to indicate the type of data, not be specific to the instance. But it's not difficult to achieve:

<xsl:template match="MyTag">
  <xsl:element name="Mytag{position()}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

position() assumes you are processing the elements using xsl:apply-templates select="MyTag". For a rule that's independent of how the elements are reached you could use

name="MyTag{count(preceding-sibling::MyTag)+1}"



Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old December 21st, 2005, 11:17 AM
Registered User
 
Join Date: Dec 2005
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you very much for your help...
With the following xslt I have exactly what I asked for...

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet 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="MyTag">
  <xsl:element name="MyTag{count(preceding-sibling::MyTag)}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

Regards,
Stefan.

 
Old February 10th, 2006, 06:49 AM
Registered User
 
Join Date: Dec 2005
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi all,

Some times ago I posted a request on how to increment a tag. I have another request that seems very complicated for me but probably not for you.
I would like to know if someone could provide me the xslt code to use to achieve my request
Sorry for the long post but it is to explain better my request

Thanks in advance.
Stefan.

First of all, I would like to sort (ascending) the elements beginning with "MyTag" (so both MyTagI and MyTagN) in function of first the dates in titi and then on the dates tyty (if 2 dates in titi are the same then I have to test tyty. Then, if the two dates in tyty are the same I have to put MyTagI first and then MyTagN)
Secondly, I would like to put an increment on all tag beginning with "MyTag" (so both MyTagI and MyTagN that will become MyTag{i}) BUT also to put the same number that is only in MytagI to MyOtherTagI (it could happen that there is more MyTagI than MyOtherTagI but not the contrary).

Here are the steps of I what I would like to achieve:

Original XML file:
----------------------------------------------------------------------
<START_A>
        <HEADER OPERATION="Import" PRIMARY="Data1">
                <tutu type="S">Myname</tutu>
                <tyty type="S">Hisname</tyty>
        </HEADER>
        <START_B>
                <HisTag>
                        <tata type='S'>TTTTTTT</tata>
                        <tete type='S'>DDDDDD</tete>
                </HisTag>
                <HisTag>
                        <tata type='S'>FFFFFFF</tata>
                        <tete type='S'>DDDDDD</tete>
                </HisTag>
                <MyTagI>
                        <toto type='S'>AA</toto>
                        <titi type='D'>01/01/2000</titi>
                        <tyty type='D'>30/01/2000</tyty>
                </MyTagI>
                <MyTagI>
                        <toto type='S'>BB</toto>
                        <titi type='D'>31/01/1900</titi>
                        <tyty type='D'>30/01/1900</tyty>
                </MyTagI>
                <MyTagI>
                        <toto type='S'>ZZ</toto>
                        <titi type='D'>13/06/1930</titi>
                        <tyty type='D'>30/06/1990</tyty>
                </MyTagI>
                <MyTagN>
                        <toto type='S'>CC</toto>
                        <titi type='D'>12/06/1920</titi>
                        <tyty type='D'>30/06/1920</tyty>
                </MyTagN>
                <MyTagN>
                        <toto type='S'>WW</toto>
                        <titi type='D'>13/06/1930</titi>
                        <tyty type='D'>30/06/1990</tyty>
                </MyTagN>
                <MyOtherTagI>
                        <tutu type='S'>BB</tutu>
                </MyOtherTagI>
                <MyOtherTagI>
                        <tutu type='S'>YY</tutu>
                </MyOtherTagI>
                <HerTag>
                        <tatatata type='S'>TATATATATATAT</tatatata>
                        <tetetete type='S'>DEDEDEDED</tetetete>
                </HerTag>
        </START_B>
</START_A>
----------------------------------------------------------------------


Intermediate XML file with "MyTag?" sorted by titi and tyty dates:
----------------------------------------------------------------------
<START_A>
        <HEADER OPERATION="Import" PRIMARY="Data1">
                <tutu type="S">Myname</tutu>
                <tyty type="S">Hisname</tyty>
        </HEADER>
        <START_B>
                <HisTag>
                        <tata type='S'>TTTTTTT</tata>
                        <tete type='S'>DDDDDD</tete>
                </HisTag>
                <HisTag>
                        <tata type='S'>FFFFFFF</tata>
                        <tete type='S'>DDDDDD</tete>
                </HisTag>
                <MyTagI>
                        <toto type='S'>BB</toto>
                        <titi type='D'>31/01/1900</titi>
                        <tyty type='D'>30/01/1900</tyty>
                </MyTagI>
            <MyTagN>
                        <toto type='S'>CC</toto>
                        <titi type='D'>12/06/1920</titi>
                        <tyty type='D'>30/06/1920</tyty>
                </MyTagN>
                <MyTagI>
                        <toto type='S'>ZZ</toto>
                        <titi type='D'>13/06/1930</titi>
                        <tyty type='D'>30/06/1990</tyty>
                </MyTagI>
                <MyTagN>
                        <toto type='S'>WW</toto>
                        <titi type='D'>13/06/1930</titi>
                        <tyty type='D'>30/06/1990</tyty>
                </MyTagN>
                <MyTagI>
                        <toto type='S'>AA</toto>
                        <titi type='D'>01/01/2000</titi>
                        <tyty type='D'>30/01/2000</tyty>
                </MyTagI>
                <MyOtherTagI>
                        <tutu type='S'>BB</tutu>
                </MyOtherTagI>
                <MyOtherTagI>
                        <tutu type='S'>YY</tutu>
                </MyOtherTagI>
                <HerTag>
                        <tatatata type='S'>TATATATATATAT</tatatata>
                        <tetetete type='S'>DEDEDEDED</tetetete>
                </HerTag>
        </START_B>
</START_A>
----------------------------------------------------------------------

Expected final XML file (MyTagI and MyTagN have become MyTag[i] and MyOtherTagI has become MyOtherTag[i for MyTagI only].
The other Tag had remained the same.
----------------------------------------------------------------------
<START_A>
        <HEADER OPERATION="Import" PRIMARY="Data1">
                <tutu type="S">Myname</tutu>
                <tyty type="S">Hisname</tyty>
        </HEADER>
        <START_B>
                <HisTag>
                        <tata type='S'>TTTTTTT</tata>
                        <tete type='S'>DDDDDD</tete>
                </HisTag>
                <HisTag>
                        <tata type='S'>FFFFFFF</tata>
                        <tete type='S'>DDDDDD</tete>
                </HisTag>
                <MyTag0>
                        <toto type='S'>BB</toto>
                        <titi type='D'>31/01/1900</titi>
                        <tyty type='D'>30/01/1900</tyty>
                </MyTag0>
            <MyTag1>
                        <toto type='S'>CC</toto>
                        <titi type='D'>12/06/1920</titi>
                        <tyty type='D'>30/06/1920</tyty>
                </MyTag1>
                <MyTag2>
                        <toto type='S'>ZZ</toto>
                        <titi type='D'>13/06/1930</titi>
                        <tyty type='D'>30/06/1990</tyty>
                </MyTag2>
                <MyTag3>
                        <toto type='S'>WW</toto>
                        <titi type='D'>13/06/1930</titi>
                        <tyty type='D'>30/06/1990</tyty>
                </MyTag3>
                <MyTag4>
                        <toto type='S'>AA</toto>
                        <titi type='D'>01/01/2000</titi>
                        <tyty type='D'>30/01/2000</tyty>
                </MyTag4>
                <MyOtherTag0>
                        <tutu type='S'>BB</tutu>
                </MyOtherTag0>
                <MyOtherTag2>
                        <tutu type='S'>YY</tutu>
                </MyOtherTag2>
                <HerTag>
                        <tatatata type='S'>TATATATATATAT</tatatata>
                        <tetetete type='S'>DEDEDEDED</tetetete>
                </HerTag>
        </START_B>
</START_A>
----------------------------------------------------------------------

 
Old February 10th, 2006, 07:29 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Firstly, sorting dates is much easier if you use ISO format yyyy-mm-dd (there are other benefits, like it's directly supported in XML Schema and XSLT 2.0, and it won't be misread by Americans who seem to find the mm-dd-yyyy format natural).

Secondly, it's not a good idea to pack information into the names of your elements. If there's some relationship between MyTag3 and MyTag4, its better to use attributes: <MyTag type="3"> and <MyTag type="4">.

You should be able to do what you want with a sequence of sort keys such as

<xsl:for-each select="*[startswith(name(), 'MyTag')">
<xsl:sort select="substring(titi, 7, 4)"/>
<xsl:sort select="substring(titi, 4, 2)"/>
...
<xsl:sort select="substring(tyty, 7, 4)"/>
...
<xsl:sort select="name()"/>
  <xsl:copy-of select="."/>
</xsl:for-each>

But the problem would be much easier if you improved the design of your XML as suggested.



Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old February 13th, 2006, 02:23 PM
Registered User
 
Join Date: Dec 2005
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

First of all i can not change the structure because the software i have to send the xml is awaiting for the format i asked first
if I use the following XSLT:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
<xsl:for-each select="START_A/START_B/*[starts-with(name(), 'MyTag')]">
<xsl:sort select="substring(titi, 7, 4)"/>
<xsl:sort select="substring(titi, 4, 2)"/>
<xsl:sort select="substring(titi, 1, 2)"/>
<xsl:sort select="substring(tyty, 7, 4)"/>
<xsl:sort select="substring(tyty, 4, 2)"/>
<xsl:sort select="substring(tyty, 1, 2)"/>
<xsl:sort select="name()"/>
  <xsl:copy-of select="."/>
</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

I got
<?xml version="1.0" encoding="UTF-16"?><MyTagI>
<toto type="S">BB</toto>
<titi type="D">31/01/1900</titi>
<tyty type="D">30/01/1900</tyty>
</MyTagI><MyTagN>
<toto type="S">CC</toto>
<titi type="D">12/06/1920</titi>
<tyty type="D">30/06/1920</tyty>
</MyTagN><MyTagI>
<toto type="S">ZZ</toto>
<titi type="D">13/06/1930</titi>
<tyty type="D">30/06/1990</tyty>
</MyTagI><MyTagN>
<toto type="S">WW</toto>
<titi type="D">13/06/1930</titi>
<tyty type="D">30/06/1990</tyty>
</MyTagN><MyTagI>
<toto type="S">AA</toto>
<titi type="D">01/01/2000</titi>
<tyty type="D">30/01/2000</tyty>
</MyTagI>

Then , sorry to repeat myself but i have never developped so it is my first experience.

What about the <HEADER> the <HisTag> and all others element ? How I get them unchanged before the sorting?
Secondly how to put an increment number independently if it is MyTagI or MyTagN
Then how to put the same number in MyOtherTagI than the one in MyTagI (finally we are sure that the number of MyOtherTagI=number of MyTagI ?

Again sorry for the basics questions :$

 
Old February 14th, 2006, 06:28 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

By doing this:

<xsl:template match="/">
<xsl:for-each select="START_A/START_B/*[starts-with(name(), 'MyTag')]">

you're rushing straight into the detail. Do a standard template-based stylesheet where you descend through the source tree one level at a time, and define a template rule for each element:

<xsl:template match="START_A">
<START_A>
  <xsl:apply-templates/>
</START_A>
</xsl:template>

<xsl:template match="HEADER">
  <xsl:copy-of select="."/>
</xsl:template>

and so on. You'll find this explained in any introductory textbook.

You can generate sequence numbers in the output using position():

<xsl:element name="MyTag{position()}">

or for more complicated numbering, use xsl:number.

I'm afraid I don't understand this part of the question:

Then how to put the same number in MyOtherTagI than the one in MyTagI (finally we are sure that the number of MyOtherTagI=number of MyTagI ?



Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old February 14th, 2006, 10:23 AM
Registered User
 
Join Date: Dec 2005
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you very much for the answers.

Concerning the last part I have to rename the value of MyOtherTagI
For that I have to get the value of tutu and find MyTag{i} with the same value of tutu. Then rename MyOtherTagI into MyOtherTag{i} where {i} is the integer at the end of the found MyTag{i}
In the following example I have 2 MyOtherTagI: one's tutu value is UNIQUE1 and for the other one UNIQUE2.
The corresponding MyTag{i} with the same value of tutu are respectively MyTag0 and MyTag4
Then I have to rename the 2 MyOtherTagI into MyOtherTag0 and MyOtherTag4

Original xml:
<START_A>
        <HEADER OPERATION="Import" PRIMARY="Data1">
                <tutu type="S">Myname</tutu>
                <tyty type="S">Hisname</tyty>
        </HEADER>
        <START_B>
                <!-- only MyTag0 and
                <MyTag0>
                        <toto type='S'>BB</toto>
                        <titi type='D'>31/01/1900</titi>
                        <tyty type='D'>30/01/1900</tyty>
       <tutu type='S'>UNIQUE1</tutu>
                </MyTag0>
                <MyTag1>
                        <toto type='S'>CC</toto>
                        <titi type='D'>12/06/1920</titi>
                        <tyty type='D'>30/06/1920</tyty>
                </MyTag1>
                <MyTag4>
                        <toto type='S'>BB</toto>
                        <titi type='D'>01/01/2000</titi>
                        <tyty type='D'>30/01/2000</tyty>
       <tutu type='S'>UNIQUE2</tutu>
                </MyTag4>
                <MyOtherTagI>
                        <tutu type='S'>UNIQUE1</tutu>
                </MyOtherTagI>
                <MyOtherTagI>
                        <tutu type='S'>UNIQUE2</tutu>
                </MyOtherTagI>
        </START_B>
</START_A>

Expected xml:
<START_A>
        <HEADER OPERATION="Import" PRIMARY="Data1">
                <tutu type="S">Myname</tutu>
                <tyty type="S">Hisname</tyty>
        </HEADER>
        <START_B>
                 <MyTag0>
                        <toto type='S'>BB</toto>
                        <titi type='D'>31/01/1900</titi>
                        <tyty type='D'>30/01/1900</tyty>
                        <tutu type='S'>UNIQUE1</tutu>
                </MyTag0>
                <MyTag1>
                        <toto type='S'>CC</toto>
                        <titi type='D'>12/06/1920</titi>
                        <tyty type='D'>30/06/1920</tyty>
                </MyTag1>
                <MyTag4>
                        <toto type='S'>BB</toto>
                        <titi type='D'>01/01/2000</titi>
                        <tyty type='D'>30/01/2000</tyty>
                        <tutu type='S'>UNIQUE2</tutu>
                </MyTag4>
                <MyOtherTag0>
                        <tutu type='S'>UNIQUE1</tutu>
                </MyOtherTag0>
                <MyOtherTag4>
                        <tutu type='S'>UNIQUE2</tutu>
                </MyOtherTag4>
        </START_B>
</START_A>

 
Old February 22nd, 2006, 12:46 PM
Registered User
 
Join Date: Dec 2005
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi all,

Sorry to come back with that but has anyone an idea how to perform my last request?

Again sorry and thx in advance for your help
Stefan.

 
Old February 22nd, 2006, 02:16 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

You may find it more productive to start a new thread for a new question. The kind of thread that goes

A: I want to do X
B: here is how
A: That worked, but now I want to do Y
B: here is how
A: That worked, but now I want to do Z

quickly gets B bored with the whole business.

Keep the questions focused and simple, and separate concerns: which part of the transformation is giving you trouble?

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Auto increment prad_a MySQL 3 April 7th, 2007 05:47 AM
HTML tag from C# or ASP.NET tag from javascript angshujit ASP.NET 2.0 Basics 3 February 16th, 2007 10:07 AM
HTML tag vs Body Tag CFGerry BOOK: Beginning CSS: Cascading Style Sheets for Web Design ISBN: 978-0-7645-7642-3 1 October 7th, 2005 07:13 AM
Is it possible to increment in crystal cmdolcet Crystal Reports 2 August 14th, 2005 06:55 PM
auto increment? hosefo81 PHP Databases 1 February 2nd, 2004 03:56 PM





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