Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Looping through a sequence in a stylesheet

Status
Not open for further replies.

Stretchwickster

Programmer
Apr 30, 2001
1,746
GB
I have the following sequence as part of a complex element in my schema file:
Code:
<xsd:sequence minOccurs="2" maxOccurs="51">
 <xsd:element name="x" type="xsd:positiveInteger"/>
 <xsd:element name="y" type="xsd:positiveInteger"/>
</xsd:sequence>
In my stylesheet I want to add a pair of html table columns for each x,y pair so I'm guessing I need to use a for-each loop. I've used for-each loops for single items but how do I apply it to a sequence instead. Below is a code excerpt to illustrate what I'm trying to do.
Code:
[b]<xsl:for-each select=sequence>[/b]
 <td>
  <xsl:value-of select="x"/>
 </td>
 <td>
  <xsl:value-of select="y"/>
 </td>
</xsl:for-each>
Your help would be much appreciated!

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
What are you trying to achieve? You're generating an HTML view of the Schema?

Jon

"I don't regret this, but I both rue and lament it.
 
Sorry Jon, I should've given more background as to what I was trying to achieve. I have a data file (.xml) which contains a variable number of pairs (2 to 51) of x,y coordinates. I am performing a transformation to HTML of this data file, using a stylesheet (.xsl). What I want to do is add an extra two HTML table cells (<td> tags) for each pair of coordinates that exist. Now, normally, if it's a single item I can use a for-each loop and set the select attribute equal to the element name. However, this time I want to loop through a sequence of 2 elements as above.

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Any ideas?

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Is there some catch on your question? Using for-each should be just fine, just xpath to it correctly?
[tt]
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="html" version="1.0" encoding="UTF-8" />
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr style="background-color:#ffff00;">
<th align="left">X</th>
<th align="left">Y</th>
</tr>
<xsl:for-each select="//sequence">
<tr style="background-color:#00ffff;">
<td><xsl:value-of select="x" /></td>
<td><xsl:value-of select="y" /></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
[/tt]
Maybe I miss the point.
 
There is a close tag at the end for sure.
[tt]</xsl:stylesheet>[/tt]
 
Thanks for your reply tsuji. To be perfectly honest, I hadn't looked properly into XPath so wasn't familiar with the "//sequence" syntax.

I tried the stylesheet you provided, but the only output I get is the heading row? I think I must be misunderstanding in some way or another.

Below is the sample xml file I was applying your stylesheet to.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<coords>
  <x>1240</x>
  <y>1078</y>
  <x>1240</x>
  <y>1060</y>
  <x>1380</x>
  <y>1060</y>
  <x>1380</x>
  <y>1078</y>
</coords>

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Any chance you can change the input XML file? Something like this would be easier to use:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<coords>
 <coord>
  <x>1240</x>
  <y>1078</y>
 </coord>
 <coord>
  <x>1240</x>
  <y>1060</y>
 </coord>
 <coord>
  <x>1380</x>
  <y>1060</y>
 </coord>
 <coord>
  <x>1380</x>
  <y>1078</y>
 </coord>
</coords>

Then you can use a rather simple for-each:
Code:
...
        <xsl:for-each select="//coords/coord">
            <tr>
                <td><xsl:value-of select="x" /></td>
                <td><xsl:value-of select="y" /></td>
            </tr>
        </xsl:for-each>

Tom Morrison
 
Clive,

If you are absolutely sure about the order of your data elements, you could use something like:
Code:
    <xsl:for-each select="//coords/*">
        <xsl:choose>
        <xsl:when test="local-name(.) = 'x'">
            <tr><td><xsl:value-of select="." /></td>
        </xsl:when>
        <xsl:when test="local-name(.) = 'y'">
            <td><xsl:value-of select="." /></td></tr>
        </xsl:when>
        </xsl:choose>
    </xsl:for-each>

It is ugly, but it might just do the job...

Tom Morrison
 
Such as this for a preliminary take.
[tt]
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="html" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="//coords">
<html>
<body>
<table border="1">
<tbody>
<tr style="background-color:#ffff00;">
<th>X</th>
<th>Y</th>
</tr>
<xsl:for-each select="x">
<xsl:variable name="x_pos" select="position()" />
<xsl:variable name="x_par" select=".." />
<tr style="background-color:#00ffff;">
<td><xsl:value-of select="." /></td>
<td><xsl:value-of select="$x_par/y[$x_pos]" /></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
[/tt]
There are rooms to much improve in presentation. But it should give separate table for different coords sets.
 
I would probably do something like this:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"[/URL] xmlns:fo="[URL unfurl="true"]http://www.w3.org/1999/XSL/Format">[/URL]
  <xsl:template match="/">
    <html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
      <head>
        <title>Sequence</title>
      </head>
      <body>
        <table>
          <xsl:apply-templates select="//x"/>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="x">
    <tr>
      <td>
        <xsl:value-of select="."/>
      </td>
      <td>
        <xsl:value-of select="following-sibling::node()"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

Jon

"I don't regret this, but I both rue and lament it.
 
Thanks for all the replies people. I will post feedback here when I've had a chance to try out and explore each piece of code.

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top