Jump to content
Volker

how to insert table row attribute

Recommended Posts

Hi,i have an xml structure like this:

	<Word>  <Chinese>...</Chinese>  <PinYin>...</PinYin>	</Word>	<Word>  <Chinese>...</Chinese>  <PinYin>...</PinYin>	</Word>        

and i want a table which is sorted by "PinYin" and contains 20 columns each row containing only the data of "Chinese":0 1 2 3 4 ... 1920 21 22 23 24 ... 29...I tried with the following xsl, which gaves me the plain text result

<xsl:for-each select="ChineseWordList">  <xsl:for-each select="Word">    <xsl:sort select="PinYin"/>    <xsl:value-of select="Chinese"/>    <xsl:copy-of select="'  '"/>    <xsl:if test="position() mod 20 = 0"><br></br></xsl:if>  </xsl:for-each></xsl:for-each>

How could the code be changed to use a table?Replacing the br with tr doesn't work, because it must be closed and openend at the same line.

Share this post


Link to post
Share on other sites

I don't think this needs much modification:

<table><xsl:for-each select="ChineseWordList"> <xsl:for-each select="Word">   <xsl:sort select="PinYin"/>   <xsl:if test="position() mod 20 = 1">     <tr>   <xsl:if>   <td>   <xsl:value-of select="Chinese"/>   <xsl:copy-of select="'  '"/>   </td>   <xsl:if test="position() mod 20 = 0">     </tr>   </xsl:if> </xsl:for-each></xsl:for-each><table>

the only thing that might occur is an error because if the unmatched <tr> and </tr> tags in the xsl:if statements.Hope this helps, sorry if it doesn't :)Dooberry.

Share this post


Link to post
Share on other sites
the only thing that might occur is an error because if the unmatched <tr> and </tr> tags in the xsl:if statements.
thx for the reply dooberry, the unmatched tr and /tr elements are the major point.At the moment i'm not aware of how to place them.Maybe i have to write something like:write tr, write first 20 elements and than attach the closing tr. continue this loop with the next 20 elements until all have been processed. My experience with xsl is not much , so i'm a bit lost finding a way moving thru the sorted nodetree this way.Volker

Share this post


Link to post
Share on other sites

What about trying

<xsl:value-of select="'<tr>'" /><xsl:value-of select="'</tr>'" />

instead?I'm wondering if these text values will work by not being part of the html in the stylesheet.I've used this technique before to tell xsl to use a text value in value-of instead of select a node value.I'll try it and see what the results are.As these

Share this post


Link to post
Share on other sites
What about trying
<xsl:value-of select="'<tr>'" /><xsl:value-of select="'</tr>'" />

instead?I'm wondering if these text values will work by not being part of the html in the stylesheet.I've used this technique before to tell xsl to use a text value in value-of instead of select a node value.I'll try it and see what the results are.As these

I already know the answer. It won't work, because "<" and ">" are invalid inside elements including atribute values. Replacing them with entities is going to make only plain text.Creating "invalid" XSLT code is what I think we can call the holy grail of XSLT :) .

Share this post


Link to post
Share on other sites

I've cracked it but I've also found something odd with the position() function.here is something that worked:

<xsl:template match="item"><xsl:for-each select=".">     <td>     <xsl:value-of select="." />     </td></xsl:for-each><xsl:if test="position() mod 4 = 0" ><tr /></xsl:if></xsl:template>

As a programmer it doesn't seem logical that the position() function has to be outside the for-each statement.This works because when the expression evaluates to 0 the <tr /> is added which is a closed table row (a table row with nothing in it!!).This is a shortcut for <tr></tr> that would work in place of <tr /> in the above code.I knew I'd get it in the end :)

All things meritorious are as difficult as they are rare!!
Dooberry :)

Share this post


Link to post
Share on other sites
Guest Vinz
I've cracked it but I've also found something odd with the position() function.here is something that worked:
<xsl:template match="item"><xsl:for-each select=".">     <td>     <xsl:value-of select="." />     </td></xsl:for-each><xsl:if test="position() mod 4 = 0" ><tr /></xsl:if></xsl:template>

As a programmer it doesn't seem logical that the position() function has to be outside the for-each statement.This works because when the expression evaluates to 0 the <tr /> is added which is a closed table row (a table row with nothing in it!!).This is a shortcut for <tr></tr> that would work in place of <tr /> in the above code.I knew I'd get it in the end :)Dooberry :)

It works but it seems to produce invalid HTML doesn't it?

Share this post


Link to post
Share on other sites

Unfortunatly, that's too true. I was just able to run Cold Fusion's XSLT processor and with this XML:

<?xml version="1.0" encoding="windows-1251"?><?xml-stylesheet type="text/xsl" href="dictionary.xsl"?><Dictionary><Word> <Chinese>A</Chinese> <PinYin>B</PinYin></Word><Word> <Chinese>C</Chinese> <PinYin>D</PinYin></Word><Word> <Chinese>E</Chinese> <PinYin>F</PinYin></Word><Word> <Chinese>G</Chinese> <PinYin>H</PinYin></Word><Word> <Chinese>I</Chinese> <PinYin>J</PinYin></Word><Word> <Chinese>K</Chinese> <PinYin>L</PinYin></Word><Word> <Chinese>M</Chinese> <PinYin>N</PinYin></Word><Word> <Chinese>O</Chinese> <PinYin>P</PinYin></Word><Word> <Chinese>Q</Chinese> <PinYin>R</PinYin></Word><Word> <Chinese>S</Chinese> <PinYin>T</PinYin></Word><Word> <Chinese>U</Chinese> <PinYin>V</PinYin></Word><Word> <Chinese>W</Chinese> <PinYin>X</PinYin></Word><Word> <Chinese>Y</Chinese> <PinYin>Z</PinYin></Word><Word> <Chinese>1</Chinese> <PinYin>2</PinYin></Word><Word> <Chinese>3</Chinese> <PinYin>4</PinYin></Word><Word> <Chinese>5</Chinese> <PinYin>6</PinYin></Word><Word> <Chinese>7</Chinese> <PinYin>8</PinYin></Word><Word> <Chinese>9</Chinese> <PinYin>10</PinYin></Word><Word> <Chinese>11</Chinese> <PinYin>12</PinYin></Word><Word> <Chinese>13</Chinese> <PinYin>14</PinYin></Word></Dictionary>

This XSLT

<?xml version="1.0" encoding="windows-1251"?><!-- DWXMLSource="dictonary.xml" --><!DOCTYPE xsl:stylesheet  [	<!ENTITY nbsp   " ">	<!ENTITY copy   "©">	<!ENTITY reg    "®">	<!ENTITY trade  "™">	<!ENTITY mdash  "—">	<!ENTITY ldquo  "“">	<!ENTITY rdquo  "”"> 	<!ENTITY pound  "£">	<!ENTITY yen    "¥">	<!ENTITY euro   "€">]><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" encoding="windows-1251"doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/><xsl:template match="/Dictionary"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/><title>Untitled Document</title><style type="text/css">td {border: 1px solid #000000;}tr {border: 1px solid #FF0000;}</style></head><body><table><xsl:apply-templates select="Word" /></table></body></html></xsl:template><xsl:template match="Word"><xsl:for-each select=".">    <td>    <xsl:value-of select="." />    </td></xsl:for-each><xsl:if test="position() mod 4 = 0" ><tr /></xsl:if></xsl:template></xsl:stylesheet>

And this cfm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta content="text/html; charset=windows-1251" http-equiv="Content-Type" /><title>Untitled Document</title><style type="text/css">td {border: 1px solid #000000;}tr {border: 1px solid #FF0000;}</style><META NAME="ColdFusionMXEdition" CONTENT="ColdFusion DevNet Edition - Not for Production Use."></head><body><table><td xmlns=""> A B</td><td> C D</td><td> E F</td><td> G H</td><td> I J</td><tr></tr><td> K L</td><td> M N</td><td> O P</td><td> Q R</td><td> S T</td><tr></tr><td> U V</td><td> W X</td><td> Y Z</td><td> 1 2</td><td> 3 4</td><tr></tr><td> 5 6</td><td> 7 8</td><td> 9 10</td><td> 11 12</td><td> 13 14</td><tr></tr></table></body></html>

As you can see for yourself, it's all invalid.

Share this post


Link to post
Share on other sites

Hi,if i use this structure of xml:

...<Word>  <Chinese>你</Chinese>  <PinYin>nǐ</PinYin>  <PinYinNumber>ni3</PinYinNumber>	</Word>	<Word>  <Chinese>好</Chinese>  <PinYin>hǎo</PinYin>                <PinYinNumber>ha3o</PinYinNumber>	</Word>...

with this xslt:

      <table border="0" cellpadding="1" rules="all" width="100%">               <xsl:for-each select="ChineseWordList">                    <xsl:for-each select="Word">                         <xsl:sort select="PinYinNumber"/>                         <td><xsl:value-of select="Chinese"/></td>                         <xsl:if test="position() mod 8 = 0"><tr /></xsl:if>                    </xsl:for-each>               </xsl:for-each>               </table>

I get the following result(values doesn't match the contents from the XML above, but ...).

<table border="0" cellpadding="1" rules="all" width="100%"><td>爱人</td><td>班</td><td>班</td><td>帮助</td><td>包</td><td>爸爸</td><td>办公室</td><tr />...</table>

which is just displayed perfectly inside IE or FireFox(Using XMLSpy).Volker

Share this post


Link to post
Share on other sites

That's what me and Vinz said actually. It displays correctly in both browsers, but technically speaking, it's not a valid XHTML output code. This is the only solution which you would have to stick with now, but if you're looking for a valid output, you should try to create something else as well.

Share this post


Link to post
Share on other sites

I must say I now feel both as a noob and a guru. A noob for my previous statement that insterting invalid code is like a holy grail. Guru, for discovering that holy grail :) . It's an element I avoid using. Who would have though how life saving <xsl:text> could be?!?!

 <?xml version="1.0" encoding="windows-1251"?><!-- DWXMLSource="dictonary.xml" --><!DOCTYPE xsl:stylesheet  [	<!ENTITY nbsp   " ">	<!ENTITY copy   "©">	<!ENTITY reg    "®">	<!ENTITY trade  "™">	<!ENTITY mdash  "—">	<!ENTITY ldquo  "“">	<!ENTITY rdquo  "”"> 	<!ENTITY pound  "£">	<!ENTITY yen    "¥">	<!ENTITY euro   "€">]><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" encoding="windows-1251"doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/><xsl:template match="/Dictionary"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/><title>Untitled Document</title><style type="text/css">td {border: 1px solid #000000;}tr {border: 1px solid #FF0000;}.PinYin {text-align: right;}.Chinese {text-align: left;}</style></head><body><table><xsl:for-each select="Word"><xsl:variable name="columns">4</xsl:variable>  <xsl:if test="position() mod $columns=1">    <xsl:text disable-output-escaping="yes"><tr></xsl:text>  </xsl:if>  <td>  <span class="{local-name(Chinese)}"><xsl:value-of select="Chinese"/></span>  <span class="{local-name(PinYin)}"><xsl:value-of select="PinYin"/></span>  </td>  <xsl:if test="position() mod $columns=0">    <xsl:text disable-output-escaping="yes"></tr></xsl:text>  </xsl:if></xsl:for-each></table></body></html></xsl:template></xsl:stylesheet> 

Produces completely valid code :) . The only problem is that if ran directly by Firefox or Opera 9 Build 8219, you see plain text instead. That's actually a wrong behaviour I think, but still. If you parse it on the server side, it displays and comes valid in all browsers.Note that I've used the XML I provided in my second last post.Does anyone know how could I (or you by yourself) report this to both Opera and Mozilla?[edit]Reported to both Mozilla and Opera. Opera doesn't say anything yet It turned out Opera had a newer bild (8367) which now supports disable-output-escaping and as for Mozilla, this issue turned out to be a very frequently reported one and they don't intend on fixing it. See bug 98168 for details. In the mean time, I found another solution in the bug itself. Someone posted a "challenge" for the exact same idea here and one person was able to solve the issue. Here's the solution, adopted for this XML of course:

<?xml version="1.0" encoding="windows-1251"?><!-- DWXMLSource="dictonary.xml" --><!DOCTYPE xsl:stylesheet  [	<!ENTITY nbsp   " ">	<!ENTITY copy   "©">	<!ENTITY reg    "®">	<!ENTITY trade  "™">	<!ENTITY mdash  "—">	<!ENTITY ldquo  "“">	<!ENTITY rdquo  "”"> 	<!ENTITY pound  "£">	<!ENTITY yen    "¥">	<!ENTITY euro   "€">]><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" encoding="windows-1251"doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/><xsl:param name="group-size" select="4" /><xsl:template match="/Dictionary"><html xmlns="http://www.w3.org/1999/xhtml">	<head>		<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/>		<title>Untitled Document</title>		<style type="text/css">		<xsl:comment>			td {border: 1px solid #000000;}			tr {border: 1px solid #FF0000;}			.Chinese {text-align: left;}			.PinYin {text-align: right;}		</xsl:comment>		</style>		</head>		<body> 			<table> 				<xsl:apply-templates select="Word[(position() mod $group-size) = 1]" /> 			</table> 		</body> 	</html> </xsl:template><xsl:template match="Word"> 	<tr> 		<xsl:for-each select=". | following-sibling::Word[position() < $group-size]"> 			<td>				<span class="Chinese"><xsl:value-of select="Chinese" /></span>				<span class="PinYin"><xsl:value-of select="PinYin" /></span>			</td> 		</xsl:for-each> 	</tr> </xsl:template></xsl:stylesheet> 

Stupid mozilla :) .[/edit]

Edited by boen_robot

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...