simplexml_load_string 没有解析我的 XML 字符串.字符集问题? [英] simplexml_load_string not parsing my XML string. Charset issue?

查看:34
本文介绍了simplexml_load_string 没有解析我的 XML 字符串.字符集问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using the following PHP code to read XML data from NOAA's tide reporting station API:

$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);

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

Unfortunately, I end up with it displaying this:

object(SimpleXMLElement)#246 (0) { }

object(SimpleXMLElement)#246 (0) { }

在我看来,XML 的格式非常完美——为什么不解析?从看另一个问题(Simplexml_load_string() 无法解析错误) 我知道标头可能是问题所在 - http 调用确实返回了ISO-8859-1"的字符集值.但是添加 utf8_encode() 调用似乎并不能解决问题.

It looks to me like the XML is perfectly well-formed - why won't this parse? From looking at another question (Simplexml_load_string() fail to parse error) I got the idea that the header might be the problem - the http call does indeed return a charset value of "ISO-8859-1". But adding in the utf8_encode() call doesn't seem to do the trick.

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

What's especially confusing is that simplexml_load_string() doesn't actually fail - it returns a cheerful XML array, just with nothing in it!

推荐答案

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

You've been fooled (and had me fooled) by the oldest trick in the SimpleXML book: SimpleXML doesn't parse the whole document into a PHP object, it presents a PHP API to an internal structure. Functions like var_dump can't see this structure, so don't always give a useful idea of what's in the object.

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

The reason it looks "empty" is that it is listing the children of the root element which are in the default namespace - but there aren't any, they're all in the "soapenv:" namespace.

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

To access namespaced elements, you need to use the children() method, passing in the full namespace name (recommended) or its local prefix (simpler, but could be broken by changes in the way the file is generated the other end). To switch back to the "default namespace", use ->children(null).

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

So you could get the ID attribute of the first stationV2 element like this (live demo):

// 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.

I've written some debugging functions to use with SimpleXML which should be much less misleading than var_dump etc. Here's a live demo with your code and simplexml_dump.

这篇关于simplexml_load_string 没有解析我的 XML 字符串.字符集问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆