Hi I have this done using xml, php and css for styling.
But is it possible to have information in an xml file. And use xslt to display the information in a table. I have a PHP and javascript file as well.
XML file
<?xml version="1.0"?>
<TT>
<BUS>
<NUMBER>120</NUMBER>
<LEAVING>Howth</LEAVING>
<DESTINATION>Dublin Airport</DESTINATION>
<TIME>06:00, 07:00, 08:10, 9:10, 10:00,
11:25, 12:00, 13:00, 14:00, 15:20, 16:00, 17:00, 18:00</TIME>
</BUS>
</TT>
PHP
<?php
$id=$_GET['q'];
$dom=new DOMDocument;
$dom->load( 'routes.xml' );
$col=$dom->getElementsByTagName('NUMBER');
if( $col ){
foreach( $col as $node ){
if( $node->nodeType==XML_ELEMENT_NODE && $node->nodeValue==$id ) {
$parent=$node->parentNode;
}
}
$html=array();
$html[]='
</br>
<table border="2">
<tr>
<th>NUMBER</th>
<th>LEAVING</th>
<th>DESTINATION</th>
<th>TIME</th>
</tr>
<tr>';
foreach( $parent->childNodes as $node ){
if( $node->nodeType==XML_ELEMENT_NODE ) $html[]='<td>'.$node- >nodeValue.'</td>';
}
$html[]='</tr><tr background-color: #f2f2f2></table>';
echo implode( PHP_EOL, $html );
}
?>
JavaScript
function showBus(str){
if (str==""){
document.getElementById("txtHint").innerHTML="";
return;
}
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","getbus.php?q="+str,true);
xmlhttp.send();
}
HTML
<body>
<form>
<h3>Select your bus route:</h3>
<select name="NUMBER" onchange="showBus(this.value)">
<option value="">Select a Bus:</option>
<option value="15">15</option>
<option value="22">22</option>
<option value="37">37</option>
<option value="44">44</option>
<option value="120">120</option>
</select>
<div id="txtHint"><b>Bus info will be listed here...</b></div>
</form>
</body>
</html>
I want to display the xml data with each BUS Number in the menu, when you click on the number the information such as destination time is displayed in a table, but i want it using xslt not html.
Indeed it can all be done using XSLT rather than PHP, it's a bit more involved but it can be done. I still have the original XSL file you posted with the original question and have modified it slightly here.
routes.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- we want to output html -->
<xsl:output method='html' standalone='yes' indent='yes' encoding='utf-8'/>
<!-- this is the important bit, the bus number ~ id -->
<xsl:param name="id">id</xsl:param>
<xsl:template match="/">
<table border="1">
<tr bgcolor="#9acd32">
<th>NUMBER</th>
<th>LEAVING</th>
<th>DESTINATION</th>
<th>TIME</th>
</tr>
<xsl:for-each select="TT/BUS">
<xsl:choose><!-- perform a test using the supplied id param -->
<xsl:when test="NUMBER=$id">
<tr>
<td><xsl:value-of select="NUMBER"/></td>
<td><xsl:value-of select="LEAVING"/></td>
<td><xsl:value-of select="DESTINATION"/></td>
<td><xsl:value-of select="TIME"/></td>
</tr>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
getbus.php
<?php
$id=$_GET['q'];
/* Create DOMDocument for the xml */
$dom=new DOMDocument;
$dom->load( __DIR__.DIRECTORY_SEPARATOR.'routes.xml' );
/* Create the xslt processor & import stylesheet */
$proc=new XSLTProcessor();
$xsl = new DOMDocument;
$xsl->load( __DIR__.DIRECTORY_SEPARATOR.'routes.xsl' );
$proc->importStyleSheet( $xsl );
/* ! set the parameter to use in the stylesheet ! */
$proc->setParameter('', 'id', $id );
/* Transform the xml and display result */
if( $html = $proc->transformToXML( $dom ) ){ echo $html; }
/* tidy up */
$dom = $xsl = $proc = $html = null;
?>
To allow user to add a route
You need a form, you need to be able to identify the user, you need to have a location to store the generated xml files and probably a whole heap of other things too. So, very quickly:
<!doctype html>
<html>
<head>
<title>Generate xml for Bus Route</title>
</head>
<body>
<form name='usrxml' method='post'>
<input type='text' name='number' placeholder='Bus number' />
<input type='text' name='depart' placeholder='Departing from' />
<input type='text' name='destination' placeholder='Travelling to' />
<input type='text' name='times' placeholder='Times of travel' />
<input type='submit' value='Create xml' />
</form>
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
/* username??? */
$username='fred.bloggs';
$filename=__DIR__.DIRECTORY_SEPARATOR.$username.'bus_route.xml';
$number = $_POST['number'];
$depart = $_POST['depart'];
$destination = $_POST['destination'];
$times = $_POST['times'];
$dom=new DOMDocument('1.0', 'utf-8' );
$root=$dom->appendChild( $dom->createElement('TT') );
$bus=$root->appendChild( $dom->createElement('BUS') );
$bus->appendChild( $dom->createElement('NUMBER', $number ) );
$bus->appendChild( $dom->createElement('LEAVING', $depart ) );
$bus->appendChild( $dom->createElement('DESTINATION', $destination ) );
$bus->appendChild( $dom->createElement('TIME', $times ) );
$dom->save( $filename );
echo 'Route added to: '.$filename;
}
?>
</body>
</html>
Here is a pure XSLT solution without PHP. It uses no PHP, no JavaScript (except linking to an off-the-self library). It is pure Html, CSS and XSLT 2.0.
Given this input document, located with relative URL, buses.xml
...
<TT>
<BUS>
<NUMBER>120</NUMBER>
<LEAVING>Howth</LEAVING>
<DESTINATION>Dublin Airport</DESTINATION>
<TIME>06:00, 07:00, 08:10, 9:10, 10:00,
11:25, 12:00, 13:00, 14:00, 15:20, 16:00, 17:00, 18:00</TIME>
</BUS>
<BUS>
<NUMBER>200</NUMBER>
<LEAVING>Sydney</LEAVING>
<DESTINATION>Melbourne</DESTINATION>
<TIME>06:01, 07:01, 08:11, 9:11, 10:01,
11:25, 12:00, 13:00, 14:00, 15:20, 16:00, 17:01</TIME>
</BUS>
</TT>
... the interactive bus time-tables can viewed by this host page, with URL ...
<html>
<head>
<title>Bus time-tables</title>
<link href="buses.css" rel=stylesheet type="text/css">
<script type="text/javascript" language="javascript" src="js/Saxonce/Saxonce.nocache.js"></script>
<script type="application/xslt+xml" language="xslt2.0" src="buses.xsl" data-source="buses.xml"></script>
</head>
<body>
<form>
<h3>Select your bus route:</h3>
<div id="bus-options"></div>
</form>
<table>
<thead>
<tr>
<th>Bus number</th>
<th>Departing from</th>
<th>Arriving at</th>
<th>Schedule</th>
</tr>
</thead>
<tbody id="bus-rows"></tbody>
</table>
</body>
</html>
... which when loaded by the browser, leverages XSLT 2.0 stylesheet located at url buses.xsl
...
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT"
xmlns:prop="http://saxonica.com/ns/html-property"
xmlns:style="http://saxonica.com/ns/html-style-property"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs prop"
extension-element-prefixes="ixsl"
version="2.0">
<xsl:template match="/">
<xsl:result-document href="#bus-options" method="ixsl:replace-content">
<select name="NUMBER">
<option value="">Select a Bus:</option>
<xsl:apply-templates select="TT/BUS" mode="bus-option" />
</select>
</xsl:result-document>
</xsl:template>
<xsl:template match="BUS" mode="bus-option">
<option value="{NUMBER}"><xsl:value-of select="NUMBER"/></option>
</xsl:template>
<xsl:template match="select[@name='NUMBER']" mode="ixsl:onclick">
<xsl:variable name="bus" select="@prop:value"/>
<xsl:for-each select="ixsl:source()/TT/BUS[NUMBER eq $bus]">
<xsl:result-document href="#bus-rows" method="ixsl:replace-content">
<tr>
<td><xsl:value-of select="$bus"/></td>
<td><xsl:value-of select="LEAVING"/></td>
<td><xsl:value-of select="DESTINATION"/></td>
<td>
<ul>
<xsl:for-each select="tokenize(TIME,',')">
<li><xsl:value-of select="."/></li>
</xsl:for-each>
</ul>
</td>
</tr>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:transform>
A CSS stylesheet is required at relative url buses.css
. I used this content, but it is not important. ...
table {
border-collapse: collapse;
}
td,
th {
border: 1px solid #999;
padding: 0.5rem;
text-align: left;
}
td {
background: hsl(150, 50%, 50%);
}
And the final resource required is the Saxon/CE library. The resource should be placed at relative url js/Saxonce/Saxonce.nocache.js
.
The outcome
This is the perfect solution. The body of the table dynamically changes to match the user selection of bus. There are no call-backs. All switching is done on the client side, so performance scales very well. Data, html structure, visual styling, and business rules are neatly segregated into separate files. A user can write their own bus routes and save it in the xml file. The whole solution is small and simple.