LibXMLError XML声明仅允许在文档的开头

时间:2017-03-23 04:03:27

标签: php xml curl dom simplexml

所以我使用curl调用php页面来接收XML响应。 simplexml_load_string由于某种原因不喜欢我的xml。使用libxml_get_errors()我能够得到标题错误消息。

此处的代码:

$service_url = 'blahblahblah';
$curl = curl_init($service_url);
$curl_post_data = array(
    "action" => "LISTWORKOUT",
    "accesstoken" => $accesstoken,
    "workoutid" => 2,
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
$curl_response = curl_exec($curl);
curl_close($curl);


libxml_use_internal_errors(true);
$xml=simplexml_load_string($curl_response); //or simplexml_load_file

foreach( libxml_get_errors() as $error ) {

    print_r($error);

}

echo $curl_response;

这是打击的页面:

    $workoutid = mysql_real_escape_string($_POST['workoutid']);
        // Create the Element and Append the Child
        $result = mysql_query("SELECT * FROM `lifts` WHERE `workoutid` = $workoutid OR `sharedid` = $workoutid ",$sqlAPI);

        $xml = new DOMDocument("1.0");
        $xml->formatOutput=true;
        $workout=$xml->createElement("workout");
        $xml->appendChild($workout);

        while($row = mysql_fetch_array($result))
        {
            $lift=$xml->createElement("lift");
            $workout->appendChild($lift);

            $name=$xml->createElement("name",$row['name']);
            $lift->appendChild($name);

            $weight=$xml->createElement("weight", $row['weight']);
            $lift->appendChild($weight);


            $sets=$xml->createElement("sets",$row['sets']);
            $lift->appendChild($sets);

            $reps=$xml->createElement("reps", $row['reps']);
            $lift->appendChild($reps);


        }

        echo"<xmp>" . $xml->saveXML() . "</xmp>";

这里的好处是输出:

LibXMLError Object ( [level] => 3 [code] => 64 [column] => 11 [message] => 

XML declaration allowed only at the start of the document [file] => [line] => 1 )
<?xml version="1.0"?>
<workout>
  <lift>
    <name>Squats</name>
    <weight>45</weight>
    <sets>5</sets>
    <reps>5</reps>
  </lift>
  <lift>
    <name>Overhead Press</name>
    <weight>45</weight>
    <sets>5</sets>
    <reps>5</reps>
  </lift>
  <lift>
    <name>Deadlift</name>
    <weight>45</weight>
    <sets>1</sets>
    <reps>5</reps>
  </lift>
</workout>

请注意,echo显示的XML没有任何问题。

我认为它与这些引号有关吗?这可能是一个延伸。我已经开始尝试str_replace他们但仍然没有bueno。 enter image description here

1 个答案:

答案 0 :(得分:0)

问题中的图片和代码似乎就像你在文档中所拥有的那样:

<xmp>
  <?xml version="1.0"?>
  <workout>

也就是说,您向simplexml_load_string提供的文档的根元素是<xmp>,而不是<workout>。因此,LibXML开始从<xmp>元素解析该文档,然后点击<?xml version="1.0"?>并说,嘿,这是一个XML声明 - 不应该在这里。

为了防止添加XML声明,you can replace your $xml->saveXML() with

foreach ($xml->childNodes as $node) {
   echo $xml->saveXML($node);
}

或者查看问题PHP DomDocument output without <?xml version="1.0" encoding="UTF-8"?>remove xml version tag when a xml is created in php的其他一些答案。

我们的想法是,不是将整个事物作为文档输出,而是将代码从根开始遍历文档的所有节点,然后按顺序逐个输出。

因此,您正在以某种方式输出单个节点而不是整个文档作为文档,这会在文档的开头跳过不需要的XML声明。

另一个可能有效的方法是,make saveXML(…)只发出文档元素(root):

$xml->saveXML($xml->documentElement)

如果有效,它会发出你的workout元素及其所有后代,跳过XML声明。