xsl-list
[Top] [All Lists]

RE: converting html table to xml

2002-11-29 09:50:08
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(_dot_)H(_dot_)Kay(_at_)ntlworld(_dot_)com
work: Michael(_dot_)Kay(_at_)softwareag(_dot_)com 

-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com 
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of 
Thomas McDonald
Sent: 29 November 2002 16:04
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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



<Prev in Thread] Current Thread [Next in Thread>