XmlHTTPRequest: "XML解析错误:未找到元素"

3
所以我正在使用PHP+MySQL将数据库内容以XML格式提供给JavaScript。


$xml = "<?xml version='1.0' encoding='utf-8'?><confessions><pending>";
$pending = $m->MySqlHandler->Query("SELECT id, gender, age, confession, date_posted FROM confessions WHERE publish = 0");
foreach ($pending->Rows as $pr)
{
   list($id, $gender, $age, $confession, $dateposted) = array(
     $pr->Columns["id"]->Value,
     $pr->Columns["gender"]->Value,
     $pr->Columns["age"]->Value,
     $pr->Columns["confession"]->Value,
     $pr->Columns["date_posted"]->Value
   );
   $xml .= "<confession id='$id' gender='$gender' age='$age' dateposted='$dateposted'>$confession</confession>";
}

$xml .= "</pending>"; $xml .= "<active>"; $active = $m->MySqlHandler->Query( "SELECT DISTINCT confessions.*, (SELECT COUNT(*) FROM comments WHERE confession_id = confessions.id) AS comments, (SELECT COUNT(*) FROM sentences WHERE confession_id = confessions.id) AS sentences FROM confessions WHERE confessions.publish = 1" );
foreach ($active->Rows as $ar) { list($id, $gender, $age, $confession, $dateposted, $absolutions) = array( $ar->Columns["id"]->Value, $ar->Columns["gender"]->Value, $ar->Columns["age"]->Value, $ar->Columns["confession"]->Value, $ar->Columns["dateposted"]->Value, $ar->Columns["absolutions"]->Value ); $sql_template = "SELECT COUNT(*) FROM sentences WHERE confession_id = $id AND degree = '%s'"; $sentence_data = array( "t" => mysql_result(mysql_query(sprintf($sql_template, "t")), 0, 0), "c" => mysql_result(mysql_query(sprintf($sql_template, "c")), 0, 0), "p" => mysql_result(mysql_query(sprintf($sql_template, "p")), 0, 0), "l" => mysql_result(mysql_query(sprintf($sql_template, "l")), 0, 0) ); $xml .= "<confession absolutions='$absolutions' t='{$sentence_data['t']}' " . "c='{$sentence_data['c']}' p='{$sentence_data['p']}' " . "l='{$sentence_data['l']}' id='$id' gender='$gender' " . "age='$age'>$confession</confession>"; } $xml .= ""; header("Content-Type: application/xml"); echo $xml;


<?xml version='1.0' encoding='utf-8'?>
<confessions>
  <pending>
    <confession id="1" gender="m" age="20" dateposted="2010-02-06 05:22:57">
      Confesando.
    </confession>
  </pending>
  <active>
    <confession absolutions="0" t="0" c="0" p="0" l="0" id="2" gender="m" age="18">
      Confesion.
    </confession>
  </active>
</confessions>

我使用JavaScript来加载XML,代码如下:


function sendData(params, to, oncomplete)
{
    if (typeof oncomplete == 'undefined')
    {
        oncomplete = function() {};
    }
    if (typeof window.ActiveXObject != 'undefined' ) {
        http = new ActiveXObject("Microsoft.XMLHTTP");
        http.onreadystatechange = oncomplete;
    } else {
        http = new XMLHttpRequest();
        http.onload = oncomplete;
    }
    http.open("POST", to, false);
    http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-Length", params.length);
    http.setRequestHeader("Connection", "close");
    http.send(params);
}

...被称为这样:


// Load approval-pending data //
sendData("", "./leer/confesiones/" + sId, function()
{
   var xml = http.responseXML;
   var pending = xml.getElementsByTagName("pending").getElementsByTagName("confession");
(...)

我在这里停一下。因为当我尝试解析XML时,在Firebug中会出现以下错误:


XML Parsing Error: no element found Location: moz-nullprincipal:{7e9eab45-2f73-476d-9bdb-2370d1534f29} Line Number 1, Column 1:
^

我试着将./leer/confesiones/作为网址输入到浏览器中加载,它完全有效。 完全有效的XML。使用Firebug在“Net”下检查XHR也会显示有效的XML。控制台视图是给出错误的地方,就好像是JavaScript错误一样。但是http.responseText包含XML文本,而xml的类型是[object XMLDocument]

那么... 我错过了什么?

解决方案:修改PHP以输出JSON,并使用JavaScript适当解析它。


一些额外的内容:MySqlHandler是我自己的一个php框架的一部分。不要走那条路,因为这个对象已经经过深入测试并且可以正常工作。 - Joel A. Villarreal Bertoldi
你的示例缺少 "<?xml version='1.0' encoding='utf-8'?>" 这一部分,但从你的代码来看,它应该在那里。这只是一个复制粘贴错误吗?我建议使用像 Fiddler 这样的工具来真正查看数据传输过程中是否有正确的字符编码等问题。 - spurserh
修正了示例,XML 头已正确发送。我将使用 Fiddler 进行检查。 - Joel A. Villarreal Bertoldi
XML声明是多余的,因为它们默认已经存在。根本不需要包含它。 - bobince
4个回答

4

为了方便起见,使用一个JS库来封装所有的ajax操作。由于存在许多跨浏览器问题和陷阱,这可能只是其中之一。

我建议使用jQuery,它是最简单而且非常强大的。因此,请将以下代码添加到您的HTML文件头部标签中:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 

然后在你的JS中做如下操作:
 $.get('/leer/confesiones/', function(data) {
     console.log(data);
 });

那应该可以让你开始了。点击这里获取有关jQuery和$.get函数的更多信息。 顺便说一下,我看到你正在使用POST方法,但是对于检索数据(不是更新或删除),惯例是使用GET。
此外,考虑更改你的PHP代码,使其返回JSON格式的数据而不是XML。因此,不要再用XML标记做那个小舞蹈了,只需准备一个包含所有数据的数组,并执行以下操作:
echo json_encode($array); // voila

那个完美地起作用了。实际上,我已经在我的网页应用程序的其他地方使用它了。我不知道为什么我会认为将XML作为响应发送而不是JSON是个好主意。非常感谢! - Joel A. Villarreal Bertoldi
2
这些都很好,但是关于潜在问题(XML解析错误:未找到元素位置:moz-nullprincipal:{7e9eab45-2f73-476d-9bdb-2370d1534f29}行号1,列1)是否有结论?谢谢。 - Eugen

1
if (typeof window.ActiveXObject != 'undefined' ) {

我会首选原生的XMLHttpRequest。ActiveXObject只应作为备用方案,因为它可能会生成丑陋的ActiveX警告。

    http = new ActiveXObject("Microsoft.XMLHTTP");

意外的全局变量。记得使用var

    http.onreadystatechange = oncomplete;

onreadystatechange 被调用的情况不仅仅是在完成时。只有当 readystatechange 触发且 readyState===4 时,才应该调用 oncomplete,否则可能会尝试解析不完整或缺失的 XML。

    http.onload = oncomplete;

onload 不是 XMLHttpRequest 标准的一部分。你应该使用 onreadystatechange 来处理两个分支。


1

0
我不懂PHP,但是我看不到你取得<confession>元素的结束标签。你说输出结果格式良好,这让我感到困惑...

元素长这样:<confession [属性]>..文本在此..</confession> - Joel A. Villarreal Bertoldi
我的意思是,PHP代码的哪一部分创建了闭合的<confession>标签? - BobS
抱歉,忘记将一些“<”键入为“<”。 - Joel A. Villarreal Bertoldi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接