XML数据不会显示在表中

时间:2015-12-03 10:24:50

标签: php xml xslt xpath

我有一个带有ajax文件,php,xml和xsl文件的HTML。

我在html文件中有一个下拉菜单,其中包含不同总线路由的列表,当您选择总线路径时,会提交xmlhttp请求并显示来自xml页面的总线路径数据。当您选择新路线时,将显示详细信息,前一个路线将消失。

我的问题是,选中时数据不会出现在表格中。数据以文本形式出现,表格下方显示空表行和列。

<html>
<head>
<script>
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();
}    

</script>
</head>    

<body>

<form>
Select your bus route:
<select name="NUMBER" onchange="showBus(this.value)">
<option value="">Select a Bus:</option>
<option value="120">120</option>
<option value="15">15</option>
</select>
<div id="txtHint"><b>Bus info will be listed here...</b></div>
</form>        
</body>
</html>

PHP
<?php
$q=$_GET["q"];

$xmlDoc = new DOMDocument();
$xmlDoc->load("routes.xml");

$x=$xmlDoc->getElementsByTagName('NUMBER');

for ($i=0; $i<=$x->length-1; $i++) {
//Process only element nodes
if ($x->item($i)->nodeType==1) {
if ($x->item($i)->childNodes->item(0)->nodeValue == $q) {
$y=($x->item($i)->parentNode);
}
} 
}

$BUS=($y->childNodes);

for ($i=0;$i<$BUS->length;$i++) {
//Process only element nodes
if ($BUS->item($i)->nodeType==1) {
echo("<b>" . $BUS->item($i)->nodeName . ":</b> ");
echo($BUS->item($i)->childNodes->item(0)->nodeValue);
echo("<br>");
}
 }

 //Load the XML source
$xml = new DOMDocument;
$xml->load('routes.xml');

$xsl = new DOMDocument;
$xsl->load('routes.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

echo $proc->transformToXML($xml);


?> 

XML
<?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>

<BUS>
<NUMBER>15</NUMBER>      
<LEAVING>Clongriffin</LEAVING>
<DESTINATION>Ballyycullen road</DESTINATION>
<TIME>06:00</TIME>
<TIME>07:00</TIME>
<TIME>08:00</TIME>
<TIME>09:00</TIME>
<TIME>09:30</TIME>
</BUS>
</TT>


XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<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/NUMBER">
  <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:for-each>
  </table>
  </body>
 </html>
</xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

如果您在样式表中更改了一个部分,这似乎可以正常工作,但它不会像您的代码所暗示的那样过滤记录。

/* We are looking for a bus number given by the GET variable `q` */
$id=$_GET['q'];

/* Create the DOMDocument object */
$dom=new DOMDocument;

/* load your xml file */
$dom->load( 'routes.xml' );

/* find all nodes of type `NUMBER` */
$col=$dom->getElementsByTagName('NUMBER');

if( $col ){
    /* iterate through the DOMNode collection */
    foreach( $col as $node ){
        /* Search for a node with the given value / id / bus */
        if( $node->nodeType==XML_ELEMENT_NODE && $node->nodeValue==$id ) {
            /* We need the parent node so we can iterate through it's children */
            $parent=$node->parentNode;
        }
    }


    /* placeholder into which to generate the output */
    $html=array();
    $html[]='
    <table border=1>
        <tr>
            <th>NUMBER</th>
            <th>LEAVING</th>
            <th>DESTINATION</th>
            <th>TIME</th>
        </tr>
        <tr>';

    /* iterate through the parent's "child nodes." This is the equivalent of the `<xsl:for-each select="TT/BUS">` in the xsl */

    foreach( $parent->childNodes as $node ){
        /* We only want element nodes, add html with value to output array  */
        if( $node->nodeType==XML_ELEMENT_NODE ) $html[]='<td>'.$node->nodeValue.'</td>';
    }

    /* Close the row and the table */
    $html[]='</tr></table>';

    /* send back the response to the ajax function */
    echo implode( PHP_EOL, $html );
}

如果不使用xsl文件,以下php会有效地生成我认为正确的输出。

xsl

使用DOMDocument样式表的方式意味着它在整个xml文档上运行,这显然不是你想要的。可以将参数传递给xsl,这样就可以让你在没有 var s = confirm( 'Are you sure? :' ); if (s == true) { } 干预的情况下处理xml文件,尽管如此 - 使用初始搜索xml中节点的方法匹配的公交车号码见上面的评论。

答案 1 :(得分:0)

您的主页面中有一个javascript错误(只是移动.open和.send函数一个)(在index.html中修复)

然后你没有改变你需要的BUS,而是所有的xml文件。这在getbus.php中修复,创建一个新文档并根据NAME属性放置适当的节点。

在你的routes.xsl中还需要修复一些选择器。看看吧。

的index.html

<html>
<head>
    <script>
        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();
        }

    </script>
</head>

<body>

<form>
    Select your bus route:
    <select name="NUMBER" onchange="javascript:showBus(this.value)">
        <option value="">Select a Bus:</option>
        <option value="120">120</option>
        <option value="15">15</option>
    </select>
    <div id="txtHint"><b>Bus info will be listed here...</b></div>
</form>
</body>
</html>

getbus.php

<?php

$q = $_GET["q"];

$xml = new DOMDocument();
$xml->load("routes.xml");

$x = $xml->getElementsByTagName('NUMBER');

$nodeNumber = -1;
for ($i = 0; $i <= $x->length - 1; $i++) {
    if ($x->item($i)->nodeType == 1) {
        if ($x->item($i)->childNodes->item(0)->nodeValue == $q) {
            $nodeNumber = $i;
        }
    }
}

if ($nodeNumber != -1) {
//Load the XML source
    $elements = $xml->getElementsByTagName('BUS');

    $newDoc = new DOMDocument();
    $newDoc->appendChild($newDoc->importNode($elements->item($nodeNumber), true));

    $xsl = new DOMDocument;
    $xsl->load('routes.xsl');
    $proc = new XSLTProcessor;
    $proc->importStyleSheet($xsl); // attach the xsl rules
    echo $proc->transformToXML($newDoc);
}

?>

routes.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <th>NUMBER</th>
                        <th>LEAVING</th>
                        <th>DESTINATION</th>
                        <th>TIME</th>
                    </tr>

                    <xsl:for-each select="BUS">
                        <tr>
                            <td><xsl:value-of select="NUMBER"/></td>
                            <td><xsl:value-of select="LEAVING"/></td>
                            <td><xsl:value-of select="DESTINATION"/></td>
                            <td>
                                <xsl:for-each select="TIME">
                                    <xsl:value-of select="." />,
                                </xsl:for-each>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>