[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] converting html table to xml


Subject: RE: [xsl] converting html table to xml
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Fri, 29 Nov 2002 16:50:08 -0000

You're nearly there.

the expression
	
select="following-sibling::TD[generate-id(preceding-sibling::TD[1])=$id]
">

is wrong on two counts. Firstly, you need to use following/preceding
because the elements aren't siblings of each other (they can be
cousins). Secondly, $id is an <a> element, not a TD element. [Also, your
input uses lower case while your stylesheet uses uppercase, but I assume
that's just a typo].

Write
select="following::TD[generate-id(preceding::A[1]) = $id]"

I actually find it's not only more efficient, but also clearer, to do
these positional grouping problems using keys. Declare

<xsl:key match="TD" use="generate-id(preceding::A[1])"/>

and then, from an A, you can use the key to find all its "immediately
following" TDs.

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> Thomas McDonald
> Sent: 29 November 2002 16:04
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] converting html table to xml
> 
> 
> 
> I have an html table that looks like the one included below.  
> I want to 
> convert it to an xml file that looks like the one shown 
> below.  I haven't 
> had much luck, but I have included my xsl attempt below, but 
> it doesn't 
> quite get me what I am looking for.
> 
> Here is the sample xml
> <table>
> <tr>
> 	<td><a>lateletters</a></td>
> 	<td>xx</td>
> </tr>
> <tr>
> 	<td>yy</td>
> 	<td>zz</td>
> </tr>
> <tr>
> 	<td><a>earlyletters</a></td>
> 	<td>aa</td>
> </tr>
> <tr>
> 	<td>bb</td>
> 	<td>cc</td>
> </tr>
> </table>
> 
> Here is what I want the output to look like
> <frag>
> <letters name="lateletters">
> <letter>xx</letter>
> <letter>yy</letter>
> <letter>zz</letter>
> </letters>
> <letters name="earlyletters">
> <letter>yy</letter>
> <letter>yy</letter>
> <letter>yy</letter>
> </letters>
> </frag>
> 
> esentially, I want all the contents of a <td> tag that follow 
> an <a> tag to 
> be contained within a <letters> parent element.  Once you hit 
> a new <a> tag 
> in the document then you should start a new <letters> parent element.
> 
> Here is my shot at it that uses ids and positions, but my 
> position criteria 
> doesn't really work because it only grabs those <td>
> 
> <?xml version='1.0'?>
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output method="xml"/>
> <xsl:template match="/TABLE">
> 	<xsl:for-each select="TR/TD/A">
> 		<xsl:variable name="id" select="generate-id()"/>
> 		<letters><xsl:attribute name="name"><xsl:value-of 
> select="."/></xsl:attribute>
> 		<xsl:for-each
> 			
> select="following-sibling::TD[generate-id(preceding-sibling::T
> D[1])=$id]">
> 			<letter><xsl:value-of select="."/></letter>
> 		</xsl:for-each>
> 		<xsl:value-of select="."/>
> 		</letters>
> 	</xsl:for-each>
> </xsl:template>
> </xsl:stylesheet>
> 
> the above doesn't work, but I think it is moving in the right 
> direction.  I 
> think the real problem happens because my second 'for-each' 
> xpath, i.e., 
> "following-sibling::TD[generate-id(preceding-sibling::TD[1])=$
> id]" can't 
> select the following <td> siblings because I don't know how 
> to construct so 
> it will get the right nodes.
> 
> _________________________________________________________________
> The new MSN 8: smart spam protection and 2 months FREE*  
> http://join.msn.com/?page=features/junkmail
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 
> 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords