Subject: Re: [xsl] While copying everything, append attribute value with incremental index. From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Fri, 10 Aug 2007 21:04:36 -0700 |
Let's start by cleaning a little bit the provided code. One namespace is not referenced at all and is better deleted. Also, the match expression: @i[parent::A] is more compact and readable if specified as: A/@i Also, whenever an <xsl:apply-templates .../> instruction has no content (body), it is more readable if specified as an empty element. Yet another refactoring is to use the fact that the concat() function can have any positive number of arguments. So, the stylesheet will now look like this: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="A/@i"> <xsl:attribute name="i"> <xsl:value-of select="concat(., '_',position() )"/> </xsl:attribute> </xsl:template> </xsl:stylesheet> The main question is why position() in the last template is always 1? The answer is quite simple: this template is selected by the following xslt instruction, present in the identity rule: <xsl:apply-templates select="@*|node()"/> when the current node is an "A" element. Q: How many attributes named "i" can an element have? A: Just one Q: How many attributes (no matter their name) have the "A" elements in the provided XML document? A: Just one. Conclusion: ===> then the current node-list when the template is selected will contain just one node -- the (only) attribute of an element "A". This attribute happens to be named "i". In case "A" has more than one attribute, then the value oreturned by position() will vary and in general is implementation defined. It is a good rule that one should never rely on the ordering of attributes. I hope that this is explains why the value of position() is always 1. Now, one solution that produces the wanted results (and which will work correctly regardless of the number of attributes, their order, ..., etc. is the following: When this transformation: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="A[@i]"> <xsl:variable name="vInum"> <xsl:number count="A[@i]"/> </xsl:variable> <A i="{concat(@i,'_',$vInum)}"> <xsl:apply-templates select= "@*[not(name()='i')] | node() " /> </A> </xsl:template> </xsl:stylesheet> is performed on the provided XML document: <root> <M i="k">1</M> <A i="p"><B><C>5</C></B></A> <A i="p"><B><C>5</C></B></A> <A i="p"><B><C>5</C></B></A> </root> the wanted result is produced: <?xml version="1.0" encoding="UTF-8"?> <root> <M i="k">1</M> <A i="p_1"><B><C>5</C></B></A> <A i="p_2"><B><C>5</C></B></A> <A i="p_3"><B><C>5</C></B></A> </root> Hope this helped. Cheers, Dimitre Novatchev On 8/10/07, Xuan Ngo <xuanngo2001@xxxxxxxxx> wrote: > I would like to append the value of the attribute "p" with an incremental index using position() > function but position() is only giving me 1s. > Input: > ======== > <?xml version="1.0" encoding="UTF-8"?> > <root> > <M i="k">1</M> > <A i="p"><B><C>5</C></B></A> > <A i="p"><B><C>5</C></B></A> > <A i="p"><B><C>5</C></B></A> > </root> > > What I want: > ============= > <?xml version="1.0" encoding="UTF-8"?> > <root> > <M i="k">1</M> > <A i="p_1"><B><C>5</C></B></A> > <A i="p_2"><B><C>5</C></B></A> > <A i="p_3"><B><C>5</C></B></A> > </root> > > Output From the XSL: > ===================== > <?xml version="1.0" encoding="UTF-8"?> > <root> > <M i="k">1</M> > <A i="p_1"><B><C>5</C></B></A> > <A i="p_1"><B><C>5</C></B></A> > <A i="p_1"><B><C>5</C></B></A> > </root> > > XSL: > ====== > <?xml version="1.0" encoding="UTF-8"?> > <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:fo="http://www.w3.org/1999/XSL/Format"> > <xsl:output method="xml" encoding="UTF-8" /> > > <!-- Copy everything --> > <xsl:template match="@*|node()"> > <xsl:copy> > <xsl:apply-templates select="@*|node()"> > </xsl:apply-templates> > </xsl:copy> > </xsl:template> > > <xsl:template match="@i[parent::A]"> > <xsl:attribute name="i"><xsl:value-of select="concat(., '_')"/><xsl:value-of > select="position()"/></xsl:attribute> > </xsl:template> > > </xsl:stylesheet> > > > thx! > > > > ____________________________________________________________________________________ > Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games. > http://sims.yahoo.com/ > > -- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] While copying everything, app, Xuan Ngo | Thread | Re: [xsl] While copying everything,, Xuan Ngo |
[xsl] While copying everything, app, Xuan Ngo | Date | [xsl] counting number of occurances, Sharma, Jaikumar |
Month |