Subject: Re: [xsl] How to output open/close tags independently? From: Mike Ferrando <mikeferrando@xxxxxxxxx> Date: Thu, 26 Dec 2002 05:34:20 -0800 (PST) |
Edward, I recently did this transforming a HTML table into XML nodes. I was able to use the @colspan attribute in the TD to determine if the data was to be nested under the previous heading. I had TD[1] which was always the box number and TD[2] which was always the data. I had count(TD)=2 in every TR. I had the same problem you are talking about. I did two things. 1. I ran my nodes through a stylesheet that put a @PS attribute in each TR. This effectively numbered all nodes. <variable name="PS"> <xsl:number level="any"/> </xsl:variable> 2. I created a stylesheet that called these nodes by their value to group them into sets TR[@PS>50 and @PS<75]. 3. I wrote an empty node at the end of the table to close the last node set. 4. Using the @colspan attribute (which is a number), I was able to create a nested heirarchy of nodes by using '&<' and '&> text around each nested element. Then I searched and replaced when I was done. I then validated it. Finally, as I was thinking about this. I found that there are really only three possibilities which are encountered when transforming my HTML table. 1. colspan = next colspan 2. colspan < next colspan 3. colspan > next colspan If the condition is 1 then you just close the node. If the condition is 2 nothing is done (you are opening to deeper nodes). If the condition is 3, use the difference between the present node and the next node as the constant. This constant is used in a recursive template outputing the closing tag until the value of the difference is null. In all cases you begin the node set with the starting wrapper node which is text <xsl:text>&lt;C?&gt;</xsl:text>. The closing node will be determined by the nesting of the data. (? is the value of the current colspan.) Hope this helps, Sincerely, Mike Ferrando Washington, DC ===HTML=== <TR PS="125"> <TD valign="top" colspan="2"><B>BOX 8</B></TD> <TD valign="top" colspan="8">Biblical lore treated in great detail in Jewish encyclopedia. Review of<I>Universal Jewish Encyclopedia</I>, edited by Isaac Land.<I>Christian Science Monitor</I>, 31 July [n.d.].</TD></TR> <TR PS="126"> <TD valign="top" colspan="2"/> <TD valign="top" colspan="8">[Billings, William]</TD></TR> <TR PS="127"> <TD valign="top" colspan="3"><B>BOX 8</B></TD> <TD valign="top" colspan="7">[Liner notes for]<I>American Psalms and Fuguing Tunes</I>. Columbia Masterworks, Set M-434- AM-434-MM-434.</TD></TR> <TR PS="128"> <TD valign="top" colspan="2"><B>BOX 8</B></TD> <TD valign="top" colspan="8">The birth of opera.<I>Medical Opinion and Review</I>3, no. 11 (Nov. 1967).</TD></TR> ===XML=== &lt;C1&gt;<D1 PS="125" CT_B="8">Biblical lore treated in great detail in Jewish encyclopedia. Review of<I>Universal Jewish Encyclopedia</I>, edited by Isaac Land.<I>Christian Science Monitor</I>, 31 July [n.d.].</D1>&lt;/C1&gt; &lt;C1&gt;<D1 PS="126">[Billings, William]</D1> &lt;C2&gt;<D2 PS="127" CT_B="8">[Liner notes for]<I>American Psalms and Fuguing Tunes</I>. Columbia Masterworks, Set M-434- AM-434-MM-434.</D2>&lt;/C2&gt;&lt;/C1&gt; &lt;C1&gt;<D1 PS="128" CT_B="8">The birth of opera.<I>Medical Opinion and Review</I>3, no. 11 (Nov. 1967).</D1>&lt;/C1&gt; ===XSL=== <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output version="1.0" method="xml" indent="no" encoding="utf-8" omit-xml-declaration="no" standalone="no" media-type="text/xml"/> <xsl:param name="replace"/> <xsl:template match="/"> <xsl:text>
</xsl:text> <xsl:comment> <xsl:value-of select="concat(' Transformed with ', $replace, '.xsl ')"/> </xsl:comment> <xsl:for-each select="comment()"> <xsl:text>
</xsl:text> <xsl:comment> <xsl:value-of select="."/> </xsl:comment> </xsl:for-each> <xsl:text>
</xsl:text> <XX> <xsl:apply-templates select="//TABLE"/> <xsl:text>
</xsl:text> </XX> </xsl:template> <!-- Series 1 PS=1-52 --> <!-- 3-13; 15-22; 24-31; 33-48; 50-52 --> <!-- Series 2 PS=53-828 --> <!-- 55-774; 776; 778-828 --> <!-- Series 3 PS=829-839 --> <xsl:template match="TABLE"> <xsl:apply-templates select="TR[@PS=1]"/> <xsl:apply-templates select="TR[@PS=53]"/> <xsl:apply-templates select="TR[@PS=829]"/> </xsl:template> <!-- series ** has no subseries --> <xsl:template match="TR[@PS=829]"> <xsl:variable name="el" select="normalize-space(translate(TD[2]/H3/A[@name], ' ', '_'))"/> <xsl:text>
</xsl:text> <xsl:element name="{$el}"> <xsl:attribute name="ID"><xsl:value-of select="concat('CL', TD[2]/H3/A/@name)"/></xsl:attribute> <xsl:attribute name="CTS_B"><xsl:value-of select="substring-after(TD[1], 'BOX ')"/></xsl:attribute> <xsl:apply-templates select="following-sibling::TR[@PS>829 and @PS<840]" mode="other"/> <xsl:text>
</xsl:text> </xsl:element> </xsl:template> <xsl:template match="TR[@PS>829 and @PS<840]" mode="other"> <xsl:variable name="num" select="number(TD[1]/@colspan) -1"/> <xsl:variable name="fs_num" select="number(following-sibling::TR/TD[1]/@colspan) -1"/> <xsl:text>
		</xsl:text> <xsl:value-of select="concat('<C', TD[1]/@colspan -1, '>')"/> <xsl:element name="{concat('D', TD[1]/@colspan -1)}"> <xsl:attribute name="PS"><xsl:value-of select="@PS"/></xsl:attribute> <xsl:if test="TD[1]/A"> <xsl:attribute name="XCT_ID"><xsl:value-of select="TD[1]/A/@name"/></xsl:attribute> </xsl:if> <xsl:if test="TD[2][child::A]"> <xsl:attribute name="C11"><xsl:value-of select="concat(substring-before(TD[2]/A, ':'), ': ', substring-after(TD[2]/A, ':'))"/></xsl:attribute> <xsl:attribute name="X_TARGET"><xsl:value-of select="substring-after(TD[2]/A/@href, '#')"/></xsl:attribute> </xsl:if> <xsl:if test="string-length(TD[1])>1"> <xsl:attribute name="CT_B"><xsl:value-of select="substring-after(TD[1], 'BOX ')"/></xsl:attribute> </xsl:if> <xsl:apply-templates select="TD[2]"/> </xsl:element> <!-- greater than don't close --> <!-- equal close --> <!-- less than call count to close --> <xsl:if test="$fs_num > $num"> </xsl:if> <xsl:if test="$fs_num = $num"> <xsl:value-of select="concat('</C', $num, '>')"/> </xsl:if> <xsl:if test="$fs_num < $num"> <xsl:call-template name="count"> <xsl:with-param name="num" select="$num"/> <xsl:with-param name="fs_num" select="$fs_num"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template match="TD[2]"> <xsl:apply-templates mode="td2"/> </xsl:template> <xsl:template match="A" mode="td2"> </xsl:template> <xsl:template match="*" mode="td2"> <xsl:element name="{name()}"> <xsl:call-template name="attrib1"/> <xsl:apply-templates mode="td2"/> </xsl:element> </xsl:template> <xsl:template name="count"> <xsl:param name="num"/> <xsl:param name="fs_num"/> <xsl:choose> <xsl:when test="$fs_num < $num"> <xsl:value-of select="concat('</C', $num, '>')"/> <xsl:call-template name="count"> <xsl:with-param name="num" select="$num -1"/> <xsl:with-param name="fs_num" select="$fs_num"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="concat('</C', $num, '>')"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="attrib1"> <xsl:for-each select="@*"> <xsl:attribute name="{name()}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> </xsl:template> <xsl:template match="text()"> <xsl:value-of select="translate(., '
', '')"/> </xsl:template> </xsl:stylesheet> __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] How to output open/close tags, Edward L. Knoll | Thread | Re: [xsl] How to output open/close , Mitch Amiano |
Re: [xsl] xsl filter problem, Dimitre Novatchev | Date | RE: [xsl] How to output open/close , Passin, Tom |
Month |