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

残念ながら、これを表示することになります:

object(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属性を取得できます( live demo ):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書きました。これは、 etc.よりも誤解を招きにくいはずです。コードとsimplexml_dump.

于 2013-09-08T00:10:10.107 に答える