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!

displaying rows of data 2

Status
Not open for further replies.

Sarky78

Programmer
Oct 19, 2000
878
GB
Hi,

I ahve got an xml document that is returned from a webservice call that i need to output to the browser. the xml document details which seats are available within a theatre, and will only return the seats that are available.

I need to be able to loop over this xml document and output row by row the seats that are available.

the xml doc is like this:

<availableSeats>
<Table>
<xpos>7</xpos>
<ypos>1</ypos>
<seat_Status>4</seat_Status>
</Table>
<Table>
<xpos>7</xpos>
<ypos>2</ypos>
<seat_Status>4</seat_Status>
</Table>
<Table>
<xpos>8</xpos>
<ypos>2</ypos>
<seat_Status>4</seat_Status>
</Table>
<Table>
<xpos>9</xpos>
<ypos>3</ypos>
<seat_Status>4</seat_Status>
</Table>
</availableSeats>

what i need to be able to do is to keep an eye on the xpos element and if it changes to a different value, to start another row in my html table. Now i've experimented using variables and have found that they don't seem to allow the value to be changed once they have been set (very useful!). Can anyone point me in the direction of something that could help me with this? Without being able to make a new row dynamically I can't think how to do this.

TIA

Tony
 
XSL is the best way to do this. XSL takes XML as input and transforms it to anything you desire (normally HTML). In this case you'd want to transform the XML tabular data into HTML tabular data:

Your XML:
Code:
<availableSeats>
  <Table>
    <xpos>7</xpos>
    <ypos>1</ypos>
    <seat_Status>4</seat_Status>
  </Table>
  <Table>
    <xpos>7</xpos>
    <ypos>2</ypos>
    <seat_Status>4</seat_Status>
  </Table>
  <Table>
    <xpos>8</xpos>
    <ypos>2</ypos>
    <seat_Status>4</seat_Status>
  </Table>
  <Table>
    <xpos>9</xpos>
    <ypos>3</ypos>
    <seat_Status>4</seat_Status>
  </Table>
</availableSeats>
XSL stylesheet:
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]
  <xsl:template match="/">
    <xsl:apply-templates select="availableSeats"/>
  </xsl:template>
  <xsl:template match="availableSeats">
    <html>
      <head>
        <title>Available theatre seats</title>
      </head>
      <body>
        <table>
          <thead>
            <tr>
              <th>xpos</th>
              <th>ypos</th>
              <th>seat_Status</th>
            </tr>
          </thead>
          <tbody>
            <xsl:apply-templates select="Table"/>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Table">
    <tr>
      <td>
        <xsl:value-of select="xpos"/>
      </td>
      <td>
        <xsl:value-of select="ypos"/>
      </td>
      <td>
        <xsl:value-of select="seat_Status"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>
HTML output:
Code:
<html>
  <head>
    <title>Available theatre seats</title>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>xpos</th>
          <th>ypos</th>
          <th>seat_Status</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>7</td>
          <td>1</td>
          <td>4</td>
        </tr>
        <tr>
          <td>7</td>
          <td>2</td>
          <td>4</td>
        </tr>
        <tr>
          <td>8</td>
          <td>2</td>
          <td>4</td>
        </tr>
        <tr>
          <td>9</td>
          <td>3</td>
          <td>4</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>
You could use XSL to create a graphical representation of the theatre and show the positions of the available seats (would be cool in SVG).

Jon

"I don't regret this, but I both rue and lament it.
 
Jon,

Thanks for the quick response. I've managed to get the information output in the way that I want (should have mentioned that sorry) but what i am having problems with, is the outputting of the row information.

so what i need to be able to do is to compare the xpos value that we are currently on with the previous value. if it is the same then output the information on the same row. if the xpos is different then start a new row and so on down the document. i tried to use a variable and update that but that doesn't work.

any ideas?

Tony
 
Tony,

From your OP I think you are already using XSL, correct?

Sorting and grouping elements is a bit different in XSL but once you learn how it is done, it can be used in many situations without the use of a variable to detect control breaks - i.e. starting a new row in this case.

I would use a xsl:for-each to iterate over the Table nodes, and use an xsl:sort to sort into xpos order:
Code:
<xsl:for-each select="//availableSeats/Table">
    <xsl:sort select="xpos"/>
    <xsl:sort select="ypos"/>
        ....
</xsl:for-each>

Now comes the difficult part. If the original document is in sorted order. you can use the preceding-sibling axis to do your grouping, but that would not work with a document that is not sorted, because preceding-sibling works on document order, not on the sorted order created by xsl:sort.

I will post later on the Muench method for grouping. (Must go to a meeting right now.)

Tom Morrison
 
Tony,

Okay, here is the Muench method for grouping as applied to your document. I have scrambled the input document to demonstrate that xsl:sort is doing something.

Original document as modified:
Code:
<?xml version="1.0"?>
<availableSeats>
  <Table>
    <xpos>8</xpos>
    <ypos>2</ypos>
    <seat_Status>4</seat_Status>
  </Table>
  <Table>
    <xpos>7</xpos>
    <ypos>2</ypos>
    <seat_Status>4</seat_Status>
  </Table>
  <Table>
    <xpos>7</xpos>
    <ypos>1</ypos>
    <seat_Status>4</seat_Status>
  </Table>
  <Table>
    <xpos>9</xpos>
    <ypos>3</ypos>
    <seat_Status>4</seat_Status>
  </Table>
</availableSeats>

The Muench method:

Code:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
<xsl:output method="html"/>

[green]<!-- Add an index (key) that allows selection based on the value of xpos -->[/green]
<xsl:key name="X" match="Table" use="xpos"/>

<xsl:template match="/">
	<table border="1">
	[green]<!-- The outer for-each selects the first Table node for every unique xpos value.  In other words, the outer for-each will iterate exactly once for each unique value of xpos. -->[/green]
	<xsl:for-each select="//Table[generate-id(.)=generate-id(key('X', xpos)[1])]">
		<xsl:sort select="xpos"/>
		<tr><td><strong><xsl:text>XPOS=</xsl:text><xsl:value-of select="xpos"/></strong></td></tr>
		[green]<!-- The inner for-each iterates over all nodes that match the outer for-each xpos value -->[/green]
		<xsl:for-each select="key('X', xpos)">
			<xsl:sort select="ypos"/>
			<tr><td><xsl:text>YPOS=</xsl:text><xsl:value-of select="ypos"/></td></tr>
		</xsl:for-each>
	</xsl:for-each>
	</table>
</xsl:template>

</xsl:stylesheet>

The Muench method is named after Steve Meunch, who developed this method as the Oracle XML Evangelist.

Tom Morrison
 
I'm confused as to what you want to do. Tony, post your code. Are you using XSL?

Jon

"I don't regret this, but I both rue and lament it.
 
Jon,

All of Tony's previous questions here were about XSLT, so I jumped to the conclusion that this was also.

Tom Morrison
 
Also, for the record, XSLT 2.0, which is still a candidate recommendation, will have much better support for grouping. Look here for details. Until XSLT 2.0 is adopted and its features become available, however, the Muench method seems like the best approach.

Tom Morrison
 
Tom,

With a little tweek that has done exactly what I want it to do. Sorry about the confusion as to what i was trying to do.

Tony
 
Glad you got the question answered. Always better to post a bit of code to show exactly what you mean.

Jon

"I don't regret this, but I both rue and lament it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top