2010-05-18 2 views
3

Я делаю cURL POST и получаю ответ об ошибке назад, анализирую его в массиве, но теперь проблемы с xpath.php xpath проблемы

// XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<errors xmlns="http://host/project"> 
    <error code="30" description="[] is not a valid email address."/> 
    <error code="12" description="id[] does not exist."/> 
    <error code="3" description="account[] does not exist."/> 
    <error code="400" description="phone[] does not exist."/> 
</errors> 

// Функция/Класс

class parseXML 
{ 
    protected $xml; 

    public function __construct($xml) { 
     if(is_file($xml)) { 
      $this->xml = simplexml_load_file($xml); 
     } else { 
      $this->xml = simplexml_load_string($xml); 
     } 
    } 

    public function getErrorMessage() { 
     $in_arr = false; 
     $el = $this->xml->xpath("//@errors");   
     $returned_errors = count($el); 

     if($returned_errors > 0) { 
      foreach($el as $element) { 
       if(is_object($element) || is_array($element)) { 
        foreach($element as $item) { 
         $in_arr[] = $item; 
        } 
       } 
      } 
     } else { 
      return $returned_errors; 
     }    
     return $in_arr; 
    } 
} 

// Вызов функции

// $errorMessage is holding the XML value in an array index 
// something like: $arr[3] = $xml; 
$errMsg = new parseXML($arr[3]); 
$errMsgArr = $errMsg->getErrorMessage(); 

То, что я хотел бы это все код ошибки и описание значений атрибутов

EDIT:

ОК это print_r ($ this-> xml, true);

SimpleXMLElement Object 
(
    [error] => Array 
     (
      [0] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [code] => 30 
          [description] => [] is not a valid email address. 
         ) 

       ) 

      [1] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [code] => 12 
          [description] => Id[12345] does not exist. 
         ) 

       ) 

      [2] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [code] => 3 
          [description] => account[] does not exist. 
         ) 

       ) 

      [3] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [code] => 400 
          [description] => phone[] does not exist. 
         ) 

       ) 

     ) 

) 

для жизни меня Я не могу понять, почему я могу получить код и описание, любые мысли?

EDIT # 2 Итак, я думаю, я сломаю его.

Я использую cURL для отправки запроса на один из наших серверов, я разбираю заголовки HTTP-ответа и xml (если xml возвращается). каждая строка в заголовке/xml я взорваюсь в массив. поэтому, если есть ошибка, я вижу дополнительный индекс для массива. Затем я делаю что-то подобное.

$if_err_from_header = $http_return_response[10]; 
// I know that index 10 is where if any the error message in xml is (the one posted above). 

после того, как я это сделать:

$errMsg = new parseXML($if_err_from_header); 
$errMsgArr = $errMsg->getErrorMessage(); 

все-таки я не могу получить код и описание из атрибутов ошибочными, что мне не хватает?

EDIT # 3 Хорошо, почему это работает?

$in_arr = false; 
// This returns all the code attributes 
$el = $this->xml->xpath("//@code"); 

# if $el is false, nothing returned from xpath(), set to an empty array 
$el = $el == false ? array() : $el; 

foreach($el as $element) { 
    $in_arr[] = array("code" => $element["code"], "description" => $element["description"]); 
} 
return $in_arr; 

EDIT # 4:

Хорошо это получает, что значения я хочу, но это своего рода хак, хотел бы выбрать специфические элементы, но ...

$el = $this->xml->xpath("//*"); 

ответ

2

Убедитесь, что вы пространство имён на имя:

$this->xml->registerXPathNamespace('n', 'http://host/project'); 
$el = $this->xml->xpath("/n:errors/n:error"); 
$returned_errors = count($el); 

И пример доступа к значениям ниже.

foreach($el as $element) { 
    print "code: " . $element["code"] . "\n"; 
} 
+0

, так что просто уточнить n - это переменная, используемая для пространства имен или имя пространства имен? поэтому у меня есть xmlns, я бы использовал это или n? –

+1

@Phil, вы определили «http: // host/project» как пространство имен по умолчанию, и мы решили связать с ним префикс «n». Без указания этого пространства имен PHP пытается использовать пустое пространство имен, и поэтому выражение XPath вернет пустой набор. В качестве эксперимента создайте новый узел ошибок с атрибутом xmlns, установленным в «http: // example». Вы увидите, что он не возвращается в результатах с другими. – bleh

+0

добавил, как объект SimpleXMLElement проходит, любые мысли? –

1

@ в XPath является селектор атрибутов. Вы пытаетесь выбрать корневой элемент, так и должно быть:

$el = $this->xml->xpath("/errors"); 

Если вы хотите выбрать все элементы ошибок, используйте

$el = $this->xml->xpath("/errors/error"); 

или

$el = $this->xml->xpath("//error"); 
+0

хмм до сих пор не работает, но спасибо за указание я использую селектор атрибута –

+0

, если я просто передать индекс массива, я получаю сообщение об ошибке, это связано с индексом не является строкой. если я передам индекс в строку, я получаю 0, поскольку xpath ничего не находит. любые мысли о том, почему? –

+0

добавил, как объект SimpleXMLElement проходит, любые мысли? –