3

我正在使用以下 PHP 代码从 NOAA 的潮汐报告站 API 读取 XML 数据:

$rawxml = file_get_contents(
    "http://opendap.co-ops.nos.noaa.gov/axis/webservices/activestations/"
    ."response.jsp?v=2&format=xml&Submit=Submit"
);
$rawxml = utf8_encode($rawxml);
$ob = simplexml_load_string($rawxml);
var_dump($ob);

不幸的是,我最终显示了这个:

对象(SimpleXMLElement)#246 (0) { }

在我看来,XML 格式完美——为什么不解析?通过查看另一个问题(Simplexml_load_string() fail to parse error),我了解到标头可能是问题所在——http 调用确实返回了“ISO-8859-1”的字符集值。但是加入utf8_encode()电话似乎并没有奏效。

尤其令人困惑的是,simplexml_load_string()它实际上并没有失败——它返回了一个令人愉快的 XML 数组,只是其中没有任何内容!

4

1 回答 1

5

您已经被 SimpleXML 书中最古老的技巧所愚弄(也被我愚弄了):SimpleXML 不会将整个文档解析为 PHP 对象,而是将 PHP API 呈现给内部结构。像这样的函数var_dump看不到这个结构,所以不要总是对对象中的内容给出有用的想法。

它看起来“空”的原因是它列出了默认命名空间中的根元素的子元素 - 但没有任何子元素,它们都在“soapenv:”命名空间中。

要访问命名空间元素,您需要使用方法children()传入完整的命名空间名称(推荐)或其本地前缀(更简单,但可能会因文件在另一端生成方式的更改而被破坏)。要切换回“默认命名空间”,请使用->children(null).

所以你可以像这样获得第一个元素的ID属性(现场演示):stationV2

// Define constant for the namespace names, rather than relying on the prefix the remote service uses remaining stable
define('NS_SOAP', 'http://schemas.xmlsoap.org/soap/envelope/');

// Download the XML
$rawxml = file_get_contents("http://opendap.co-ops.nos.noaa.gov/axis/webservices/activestations/response.jsp?v=2&format=xml&Submit=Submit");
// Parse it
$ob = simplexml_load_string($rawxml);

// Use it!
echo $ob->children(NS_SOAP)->Body->children(null)->ActiveStationsV2->stationsV2->stationV2[0]['ID'];

我已经编写了一些调试函数来与 SimpleXML 一起使用,它们应该比var_dump等更容易产生误导。这是一个带有您的代码和simplexml_dump.

于 2013-09-08T00:10:10.107 回答