【问题标题】:Can't read XML with SimpleXML无法使用 SimpleXML 读取 XML
【发布时间】:2011-06-07 18:35:24
【问题描述】:

我正在通过 cUrl 接收使用 PHP 生成的 XML 代码:

$c = curl_init("http://www.domain.com/script.php");
    curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
    $xmlstr = curl_exec($c);

如果我回显 $xmlstr 变量,它会显示以下内容:

   <?xml version="1.0" encoding="utf-8"?>
        <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
        <XGetPasoParadaREGResponse xmlns="http://tempuri.org/">
        <XGetPasoParadaREGResult>
        <PasoParada><cabecera>false</cabecera>
        <e1>
        <minutos>1</minutos>
        <metros>272</metros>
        <tipo>NORMAL</tipo>
        </e1>
        <e2>
        <minutos>7</minutos>
        <metros>1504</metros>
        <tipo>NORMAL</tipo>
        </e2><linea>28
        </linea>
        <parada>376</parada>
        <ruta>PARQUE ALCOSA</ruta>
        </PasoParada>
        </XGetPasoParadaREGResult><status>1</status></XGetPasoParadaREGResponse>
        </soap:Body>

</soap:Envelope>

哪个是正确的,并且在脚本中生成的相同。但是,如果我尝试执行以下操作

$xml = simplexml_load_string($xmlstr);
    if (!is_object($xml))
        throw new Exception('Reading XML error',1001);
    echo $xml->e1->minutos;

不显示任何内容,并且 print_r 对象打印一个空对象。有什么问题?

【问题讨论】:

  • var_dump($xml) 得到什么?
  • object(SimpleXMLElement)#1 (0) { } 但字符串很好,如果保存为 XML,每个浏览器都能很好地解释。

标签: php xml simplexml


【解决方案1】:

您有两个主要问题,首先您没有考虑任何命名空间(例如soap),其次您没有遍历 XML 层次结构以获取所需的元素。

“简单”的方法是:

$minutos = (int) $xml
                     ->children('soap', TRUE)     // <soap:*>
                     ->Body                       // <soap:Body>
                     ->children('')               //   <*> (default/no namespace prefix)
                     ->XGetPasoParadaREGResponse  //   <XGetPasoParadaREGResponse>
                     ->XGetPasoParadaREGResult    //     <XGetPasoParadaREGResult>
                     ->PasoParada                 //       <PasoParada>
                     ->e1                         //         <e1>
                     ->minutos;                   //           <minutos> yay!

您还可以对值进行 XPath 查询:

// Our target node belongs in this namespace
$xml->registerXPathNamespace('n', 'http://tempuri.org/');
// Fetch <minutos> elements children to <e1>
$nodes = $xml->xpath('//n:e1/n:minutos');
// $nodes will always be an array, get the first item
$minutos = (int) $nodes[0];

值得一提的是,PHP 手册包含 basic usage examples 介绍如何遍历 XML 结构,children()registerXPathNamespace() 的特定页面通过示例向您展示了如何使用命名空间元素。

最后,如您所见,print_r()/var_dump() 与 SimpleXML 的输出并不总是很有帮助!查看所拥有内容的最佳方式是回显 saveXML(),它将显示给定元素的 XML。

【讨论】:

  • 非常感谢!我真的不擅长解析 XML,阅读的示例没有显示这种 XML,所以我认为它们是相同的。
【解决方案2】:

试试children method

foreach ($xml->children("soap", true) as $k => $v) {
    echo $k . ":\n";
    var_dump($v);
}

【讨论】:

  • 这就是它显示的内容: Body: object(SimpleXMLElement)#4 (0) { } object(SimpleXMLElement)#1 (0) { }
猜你喜欢
  • 2012-11-01
  • 1970-01-01
  • 2014-05-06
  • 2016-08-20
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 2012-10-03
  • 2016-02-05
相关资源
最近更新 更多