XML响应中的错误是什么?

时间:2011-09-13 08:00:56

标签: php xml ajax rest

我有以下php代码(getRout.php)..哪个响应导致xml格式...但是我收到了这个错误:

XML Parsing Error: no element found
Location: http://127.0.0.1/direction2/getRout.php
Line Number 1, Column 1:

修改

您可以通过请求此网址直接查看xml响应:

http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik

getRout.php

<? require_once"RESTclient.class.php";
$url="http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik";
$result=RestClient::get($url,$inputs); 
header("Content-type:text/xml");
echo($result->getResponse());?>

RESTclient.class.php

<? 

/** 
 * Class RestClient 
 * Wraps HTTP calls using cURL, aimed for accessing and testing RESTful webservice.  
 * By Diogo Souza da Silva <manifesto@manifesto.blog.br> 
 */ 
class RestClient { 

     private $curl ; 
     private $url ; 
     private $response =""; 
     private $headers = array(); 

     private $method="GET"; 
     private $params=null; 
     private $contentType = null; 
     private $file =null; 

     /** 
      * Private Constructor, sets default options 
      */ 
     private function __construct() { 
         $this->curl = curl_init(); 
         curl_setopt($this->curl,CURLOPT_RETURNTRANSFER,true); 
         curl_setopt($this->curl,CURLOPT_AUTOREFERER,true); // This make sure will follow redirects 
         curl_setopt($this->curl,CURLOPT_FOLLOWLOCATION,true); // This too 
         curl_setopt($this->curl,CURLOPT_HEADER,true); // THis verbose option for extracting the headers 
     } 

     /** 
      * Execute the call to the webservice 
      * @return RestClient 
      */  
     public function execute() { 
         if($this->method === "POST") { 
             curl_setopt($this->curl,CURLOPT_POST,true); 
             curl_setopt($this->curl,CURLOPT_POSTFIELDS,$this->params); 
         } else if($this->method == "GET"){ 
             curl_setopt($this->curl,CURLOPT_HTTPGET,true); 
             $this->treatURL(); 
         } else if($this->method === "PUT") { 
             curl_setopt($this->curl,CURLOPT_PUT,true); 
             $this->treatURL(); 
             $this->file = tmpFile(); 
             fwrite($this->file,$this->params); 
             fseek($this->file,0); 
             curl_setopt($this->curl,CURLOPT_INFILE,$this->file); 
             curl_setopt($this->curl,CURLOPT_INFILESIZE,strlen($this->params)); 
         } else { 
             curl_setopt($this->curl,CURLOPT_CUSTOMREQUEST,$this->method); 
         } 
         if($this->contentType != null) { 
             curl_setopt($this->curl,CURLOPT_HTTPHEADER,array("Content-Type: ".$this->contentType)); 
         } 
         curl_setopt($this->curl,CURLOPT_URL,$this->url); 
         $r = curl_exec($this->curl); 
         $this->treatResponse($r); // Extract the headers and response 
         return $this ; 
     } 

     /** 
      * Treats URL 
      */ 
     private function treatURL(){ 
         if(is_array($this->params) && count($this->params) >= 1) { // Transform parameters in key/value pars in URL 
             if(!strpos($this->url,'?')) 
                 $this->url .= '?' ; 
             foreach($this->params as $k=>$v) { 
                 $this->url .= "&".urlencode($k)."=".urlencode($v); 
             } 
         } 
        return $this->url; 
     } 

     /* 
      * Treats the Response for extracting the Headers and Response 
      */  
     private function treatResponse($r) { 
        if($r == null or strlen($r) < 1) { 
            return; 
        } 
        $parts  = explode("\n\r",$r); // HTTP packets define that Headers end in a blank line (\n\r) where starts the body
        while(preg_match('@HTTP/1.[0-1] 100 Continue@',$parts[0]) or preg_match("@Moved@",$parts[0])) { 
            // Continue header must be bypass 
            for($i=1;$i<count($parts);$i++) { 
                $parts[$i - 1] = trim($parts[$i]); 
            } 
            unset($parts[count($parts) - 1]); 
        } 
        preg_match("@Content-Type: ([a-zA-Z0-9-]+/?[a-zA-Z0-9-]*)@",$parts[0],$reg);// This extract the content type 
        $this->headers['content-type'] = $reg[1]; 
        preg_match("@HTTP/1.[0-1] ([0-9]{3}) ([a-zA-Z ]+)@",$parts[0],$reg); // This extracts the response header Code and Message 
        $this->headers['code'] = $reg[1]; 
        $this->headers['message'] = $reg[2]; 
        $this->response = ""; 
        for($i=1;$i<count($parts);$i++) {//This make sure that exploded response get back togheter 
            if($i > 1) { 
                $this->response .= "\n\r"; 
            } 
            $this->response .= $parts[$i]; 
        } 
     } 

     /* 
      * @return array 
      */ 
     public function getHeaders() { 
        return $this->headers; 
     } 

     /* 
      * @return string 
      */  
     public function getResponse() { 
         return $this->response ; 
     } 

     /* 
      * HTTP response code (404,401,200,etc) 
      * @return int 
      */ 
     public function getResponseCode() { 
         return (int) $this->headers['code']; 
     } 

     /* 
      * HTTP response message (Not Found, Continue, etc ) 
      * @return string 
      */ 
     public function getResponseMessage() { 
         return $this->headers['message']; 
     } 

     /* 
      * Content-Type (text/plain, application/xml, etc) 
      * @return string 
      */ 
     public function getResponseContentType() { 
         return $this->headers['content-type']; 
     } 

     /** 
      * This sets that will not follow redirects 
      * @return RestClient 
      */ 
     public function setNoFollow() { 
         curl_setopt($this->curl,CURLOPT_AUTOREFERER,false); 
         curl_setopt($this->curl,CURLOPT_FOLLOWLOCATION,false); 
         return $this; 
     } 

     /** 
      * This closes the connection and release resources 
      * @return RestClient 
      */ 
     public function close() { 
         curl_close($this->curl); 
         $this->curl = null ; 
         if($this->file !=null) { 
             fclose($this->file); 
         } 
         return $this ; 
     } 

     /** 
      * Sets the URL to be Called 
      * @return RestClient 
      */ 
     public function setUrl($url) { 
         $this->url = $url;  
         return $this; 
     } 

     /** 
      * Set the Content-Type of the request to be send 
      * Format like "application/xml" or "text/plain" or other 
      * @param string $contentType 
      * @return RestClient 
      */ 
     public function setContentType($contentType) { 
         $this->contentType = $contentType; 
         return $this; 
     } 

     /** 
      * Set the Credentials for BASIC Authentication 
      * @param string $user 
      * @param string $pass 
      * @return RestClient 
      */ 
     public function setCredentials($user,$pass) { 
         if($user != null) { 
             curl_setopt($this->curl,CURLOPT_HTTPAUTH,CURLAUTH_BASIC); 
             curl_setopt($this->curl,CURLOPT_USERPWD,"{$user}:{$pass}"); 
         } 
         return $this; 
     } 

     /** 
      * Set the Request HTTP Method 
      * For now, only accepts GET and POST 
      * @param string $method 
      * @return RestClient 
      */ 
     public function setMethod($method) { 
         $this->method=$method; 
         return $this; 
     } 

     /** 
      * Set Parameters to be send on the request 
      * It can be both a key/value par array (as in array("key"=>"value")) 
      * or a string containing the body of the request, like a XML, JSON or other 
      * Proper content-type should be set for the body if not a array 
      * @param mixed $params 
      * @return RestClient 
      */ 
     public function setParameters($params) { 
         $this->params=$params; 
         return $this; 
     } 

     /** 
      * Creates the RESTClient 
      * @param string $url=null [optional] 
      * @return RestClient 
      */ 
     public static function createClient($url=null) { 
         $client = new RestClient ; 
         if($url != null) { 
             $client->setUrl($url); 
         } 
         return $client; 
     } 

     /** 
      * Convenience method wrapping a commom POST call 
      * @param string $url 
      * @param mixed params 
      * @param string $user=null [optional] 
      * @param string $password=null [optional] 
      * @param string $contentType="multpary/form-data" [optional] commom post (multipart/form-data) as default 
      * @return RestClient 
      */ 
     public static function post($url,$params=null,$user=null,$pwd=null,$contentType="multipart/form-data") { 
         return self::call("POST",$url,$params,$user,$pwd,$contentType); 
     } 

     /** 
      * Convenience method wrapping a commom PUT call 
      * @param string $url 
      * @param string $body  
      * @param string $user=null [optional] 
      * @param string $password=null [optional] 
      * @param string $contentType=null [optional]  
      * @return RestClient 
      */ 
     public static function put($url,$body,$user=null,$pwd=null,$contentType=null) { 
         return self::call("PUT",$url,$body,$user,$pwd,$contentType); 
     } 

     /** 
      * Convenience method wrapping a commom GET call 
      * @param string $url 
      * @param array params 
      * @param string $user=null [optional] 
      * @param string $password=null [optional] 
      * @return RestClient 
      */ 
     public static function get($url,array $params=null,$user=null,$pwd=null) { 
         return self::call("GET",$url,$params,$user,$pwd); 
     } 

     /** 
      * Convenience method wrapping a commom delete call 
      * @param string $url 
      * @param array params 
      * @param string $user=null [optional] 
      * @param string $password=null [optional] 
      * @return RestClient 
      */ 
     public static function delete($url,array $params=null,$user=null,$pwd=null) { 
         return self::call("DELETE",$url,$params,$user,$pwd); 
     } 

     /** 
      * Convenience method wrapping a commom custom call 
      * @param string $method 
      * @param string $url 
      * @param string $body  
      * @param string $user=null [optional] 
      * @param string $password=null [optional] 
      * @param string $contentType=null [optional]  
      * @return RestClient 
      */ 
     public static function call($method,$url,$body,$user=null,$pwd=null,$contentType=null) { 
         return self::createClient($url) 
             ->setParameters($body) 
             ->setMethod($method) 
             ->setCredentials($user,$pwd) 
             ->setContentType($contentType) 
             ->execute() 
             ->close(); 
     } 
} 

?>

4 个答案:

答案 0 :(得分:3)

xml中没有问题。您在浏览器中看到的问题是由于xml标记开始之前的空字符。

如果你做var_dump,你会看到类似的东西:

string(5726) "               <--- carriage return
<?xml version="1.0" encoding="UTF-8"?>

你应该改变类的treatResponse()方法,我解决了这个问题:

    private function treatResponse($r) { 
       ....
        for($i=1;$i<count($parts);$i++) {
            if($i > 1) { 
                $this->response .= "\n\r"; 
            } 
            $this->response .= trim($parts[$i]); 
        } 
     } 

希望这会有所帮助

注意:该空行来自HTTP协议,该协议表明标题后面应该有一个空行http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_message

答案 1 :(得分:1)

在输出中的xml声明之前有一个换行符,因为RestClient::treatResponse($r)没有按照它应该“处理”响应; - )

我宁愿在构造函数中设置curl_setopt($this->curl,CURLOPT_HEADER, false)并将treatResponse()缩减为

private function treatResponse($r) { 
    $this->response = $r;
    $this->headers['content-type'] = curl_getinfo($this->curl, CURLINFO_CONTENT_TYPE);
    $this->headers['code'] = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
    // ok, that's not exactly the same ....
    $this->headers['message'] = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
 }

答案 2 :(得分:0)

跑你的代码 - 我得到的唯一错误是:

Notice: Undefined variable: inputs

删除$ inputs - 没有错误

答案 3 :(得分:0)

这对我有用

<?php
require_once("RESTclient.class.php");
$url="http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik";
$result=RestClient::get($url);        // removed $input as suggested by Dan J
header("Content-type:text/xml");
echo(trim($result->getResponse()));   // added trim to remove blank line before
                                      // xml declaration
?>