Subject: Re: [xsl] variable outside a for-each loop: second try From: "Mathieu Malaterre" <mathieu.malaterre@xxxxxxxxx> Date: Fri, 21 Sep 2007 15:29:54 +0200 |
On 9/20/07, Abel Braaksma <abel.online@xxxxxxxxx> wrote: > Mathieu Malaterre wrote: > > $ java -jar /usr/share/Dart/Source/Server/saxon/saxon8.jar -t > > Saxon 8.0 from Saxonica > > Java version 1.6.0_01 > > No source file name > > > > ouch, that must be at least three years old! High time to upgrade to 8.9 > at the very least! So much has changed since then. > > > <xsl:for-each select="//informaltable"> > > > > someone already told you this on this thread, but really, try to refrain > from //. It is very costly and will cause you more harm (walking the > full tree of all nodes to find whether they match 'informaltable') than > good. Just use the path as it is, in your case: select="informaltable". > > > When I tried your solution here is what I get:. > > > > <entry ie="{(entry[1]/para[. != ''] | > > preceding-sibling::row[entry[1]/para != ''][1])[1]}" > > module="{entry[2]/para}" reference="{entry[3]/para}" > > usage="{entry[4]/para}"/> > > </xsl:template> > > > > My solution was meant as a hint, not as a full solution. But my > apologies for leaving such an obvious bug into the stylesheet; that > happens when you only type them in the mail and don't try them before > sending. There are two bugs: > > 1. The obvious one: the prec-sibl statement requests for the element > "row", not for the element "para", which is what you were after. > 2. The less obvious is the one of document order: the last [1] will > select the *first* to appear in document order of the two elements > specified between the parentheses before it. That means: the prec-sibl > row will always be chosen. Change it to use the , (comma) operator or > change [1] to [last()]. > > After these fixes the @ie-statement becomes: > > {(entry[1]/para[. != ''] , preceding-sibling::row/entry[1]/para[. != > ''][1])[1]} > > > > > > Gives: > > > > <?xml version="1.0" encoding="UTF-8"?> > > <entry ie="Col1 A" module="Col2 A" reference="" usage=""/> > > <entry ie="
 
 Col1 A
 
 
 Col2 > > A
 
 " module="Col2 B" reference="" usage=""/> > > <entry ie="
 
 Col1 A
 
 
 Col2 > > A
 
 " module="Col2 C" reference="" usage=""/> > > <entry ie="
 
 Col1 A
 
 
 Col2 > > A
 
 " module="Col2 D" reference="" usage=""/> > > > > Weird behavior like this is what happens when you use a very out of date > processor that is implemented on a very old draft version of a now > completely finalized (and in quite some areas changed) specification. > The whitespace that you see is caused by the preceding-sibling::row > elements, which contain non-significant whitespace. With a correctly > behaving processor, this whitespace would normally be ignored (note that > 
 is also whitespace! It is the newline that is between <row> and > <entry> and between <entry> and <para> etc). > > The output with my original stylesheet, just as you put it above, is as > follows with a normal recent version of any XSLT 2.0 processor: > > <?xml version="1.0" encoding="UTF-8"?> > <table> > <entry ie="Col1 A" module="Col2 A" reference="" usage=""/> > <entry ie="Col1 ACol2 A" module="Col2 B" reference="" usage=""/> > <entry ie="Col1 ACol2 A" module="Col2 C" reference="" usage=""/> > <entry ie="Col1 ACol2 A" module="Col2 D" reference="" usage=""/> > </table> > > Which is not correct, of course, but vastly different from your output. > By now I hope you are convinced to upgrade your processor ;) it will > save you (and us) gazillions of time. > > This is the XSLT I used to test my bug fixes (but still: it is not more > than a hint, I am sure you want to tweak it further). Note the comma > operator and the absence of //: > > <xsl:template match="/"> > <xsl:apply-templates select="*" /> > </xsl:template> > > <xsl:template match="informaltable"> > <table> > <xsl:apply-templates /> > </table> > </xsl:template> > > <xsl:template match="row"> > <entry ie="{(entry[1]/para[. != ''] , > preceding-sibling::row/entry[1]/para[. != ''][1])[1]}" > module="{entry[2]/para}" reference="{entry[3]/para}" > usage="{entry[4]/para}"/> > </xsl:template> > > > This is the output: > > <?xml version="1.0" encoding="UTF-8"?> > <table> > <entry ie="Col1 A" module="Col2 A" reference="" usage=""/> > <entry ie="Col1 A" module="Col2 B" reference="" usage=""/> > <entry ie="Col1 A" module="Col2 C" reference="" usage=""/> > <entry ie="Col1 D" module="Col2 D" reference="" usage=""/> > </table> > > > Hope this info will help you further. Thanks, This should close the thread. I don't think I was able to describe my problem correctly using both your solution and the xsl:transform I am not getting what I called the 'last' preceeding entry. Docs are here: https://gdcm.svn.sourceforge.net/svnroot/gdcm/Sandbox/xslt/ In both case I get something like: <?xml version="1.0" encoding="UTF-8"?> <table> <entry ie="Col1 A" module="Col2 A" reference="" usage=""/> <entry ie="Col1 A" module="Col2 B" reference="" usage=""/> <entry ie="Col1 A" module="Col2 C" reference="" usage=""/> <entry ie="Col1 D" module="Col2 D" reference="" usage=""/> <entry ie="Col1 E" module="Col2 E" reference="" usage=""/> <entry ie="Col1 A" module="Col2 F" reference="" usage=""/> <entry ie="Col1 A" module="Col2 G" reference="" usage=""/> </table> The last two lines contains 'Col1 A' which is not what I called 'last' preceeding. It should have been: <?xml version="1.0" encoding="UTF-8"?> <table> <entry ie="Col1 A" module="Col2 A" reference="" usage=""/> <entry ie="Col1 A" module="Col2 B" reference="" usage=""/> <entry ie="Col1 A" module="Col2 C" reference="" usage=""/> <entry ie="Col1 D" module="Col2 D" reference="" usage=""/> <entry ie="Col1 E" module="Col2 E" reference="" usage=""/> <entry ie="Col1 E" module="Col2 F" reference="" usage=""/> <entry ie="Col1 E" module="Col2 G" reference="" usage=""/> </table> Thanks again all for your help. I did not meant to be rude. But I felt like I would ask a very simple question on the C++ newsgroup and people would tell me to use C++0x . I have ordered an XSLT book, -- Mathieu
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] variable outside a for-ea, Scott Trenda | Thread | Re: [xsl] variable outside a for-ea, Abel Braaksma |
RES: [xsl] Inserting an XSL variabl, Jonathan Dias | Date | Re: RES: [xsl] Inserting an XSL var, Abel Braaksma |
Month |