SimpleXMLElementオブジェクトから値を取得する


197

私はこのようなものを持っています:

$url = "http://ws.geonames.org/findNearbyPostalCodes?country=pl&placename=";
$url .= rawurlencode($city[$i]);

$xml = simplexml_load_file($url);
echo $url."\n";
$cityCode[] = array(
    'city' => $city[$i], 
    'lat' => $xml->code[0]->lat, 
    'lng' => $xml->code[0]->lng
);

ジオネームからXMLをダウンロードすることになっています。私がprint_r($xml)取得した場合:

SimpleXMLElement Object
(
    [code] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [postalcode] => 01-935
                    [name] => Warszawa
                    [countryCode] => PL
                    [lat] => 52.25
                    [lng] => 21.0
                    [adminCode1] => SimpleXMLElement Object
                        (
                        )

                    [adminName1] => Mazowieckie
                    [adminCode2] => SimpleXMLElement Object
                        (
                        )

                    [adminName2] => Warszawa
                    [adminCode3] => SimpleXMLElement Object
                        (
                        )

                    [adminName3] => SimpleXMLElement Object
                        (
                        )

                    [distance] => 0.0
                )

ご覧の$xml->code[0]->latとおり、オブジェクトを返します。どうすれば値を取得できますか?



@kubas回答を選択できますか?
kqw 2014年

1
2017年の更新:SOでは、最上部に最良の回答が表示されなくなりました。 最良の答えはこちらです。
rinogo 2017

2
@rinogo回答ブロックの上部にある並べ替えタブの1つを誤ってクリックした可能性があります。リンクした回答の投票数は345であるため、並べ替えを「投票」に設定すると、上部に表示されます。
IMSoP 2017

1
ありがとう、@ IMSoP!そのとおりです-私はある時点で[アクティブ]をクリックしている必要があります(回答が古くなっている古い質問に役立ちます)。:)
rinogo 2017

回答:


426

simpleXMLオブジェクトを文字列にキャストする必要があります。

$value = (string) $xml->code[0]->lat;

9
D:あなたはXMLオブジェクトをjson_encode場合だけで気づいたし、それをjson_decodeあなたが怠けていると、単純な構造で作業しているときのために非常に便利に対処するために、ネストされたstdObject取得
ルイ

1
ばかげた質問ですが、それはバグではありませんか?php.net/simplexml#95762を参照してくださいなぜ一部のフィールドで型をキャストする必要がなく、他のフィールドで型をキャストする必要があるのですか?
gcb 2014

7
この答えは、2016年もなお尻をさらにキックします!
Hirdesh Vishwdewa 16

4
これがとても複雑だなんて信じられません。「getName」ではなく「getValue」というクラスを作成するのはなぜですか。手動で(文字列)に変換する代わりに印刷した場合、なぜ空の文字列が印刷されるのでしょうか。なぜ??
user151496

1
@ user151496技術的には、文字列キャストは「値」ではなく「テキストコンテンツ」を提供します。しかし、はい、具体的に名前が付けられた方法はより発見しやすいでしょう。あなたはこれに慣れたら、しかし、それはどんな困難に実際にはありません使用
IMSoP 2017

91

マジックメソッド__toString()を使用することもできます

$xml->code[0]->lat->__toString()

5
またはsprintf%sフォーマット。Or echoおよび出力バッファリング、orまたはorまたは...
hakre

PHPでオブジェクトをXMLに変換するにはどうすればよいですか?@sglessard
Gem

17

XML要素の値が浮動小数点数(緯度、経度、距離)であることがわかっている場合は、 (float)

$value = (float) $xml->code[0]->lat;

また、(int)整数の場合:

$value = (int) $xml->code[0]->distance;

15

あなたがあればしていない XML要素の値を知って、あなたが使用することができます

$value = (string) $xml->code[0]->lat;

if (ctype_digit($value)) {
    // the value is probably an integer because consists only of digits
}

あなたは値が数値であるかどうかを判断する必要がある場合ので、作品(string)常に文字列と戻りますis_int($value)戻りますfalse


(string)$ value == 'true' ||以外のブール値もチェックする方法 (文字列)$値== 'false'?
Talisin 2014年

12

私にとっては、オブジェクトよりも配列を使用する方が簡単です。

したがって、Xml-Objectを変換し、

$xml = simplexml_load_file('xml_file.xml');    
$json_string = json_encode($xml);    
$result_array = json_decode($json_string, TRUE);

3
JSONに変換してから同じコンテキストに戻すことは、本当に急いでいない限り、信じられないほど非効率的です。オブジェクトの操作は難しくありません。配列を本当に好む場合は、オブジェクトをネイティブに配列に変換する必要があります。
ウィリアム

なぜ人々がこれを行うのか私には理解できません。SimpleXMLのすべての機能を捨てて、の$xml['foo'][0]['bar'][0]['@attributes']['baz']代わりに記述できるようにするだけです$xml->foo->bar['baz']
IMSoP 2017

2

これは常にxml関連の値を配列に変換するのに役立つ関数です

function _xml2array ( $xmlObject, $out = array () ){
    foreach ( (array) $xmlObject as $index => $node )
        $out[$index] = ( is_object ( $node ) ) ? _xml2array ( $node ) : $node;

    return $out;
}

これにより、属性、名前空間内のすべて、CDATAブロックなどが破棄または破棄されます。すべての理由で、SimpleXMLが最初に提供した便利なメソッドを失う可能性があります。
IMSoP 2017

1

試す current($xml->code[0]->lat)

配列の現在のポインタ(0)の下に要素を返すため、値を取得します


1

'{}'を使用してプロパティにアクセスし、必要に応じて実行できます。保存するか、コンテンツを表示します。

    $varName = $xml->{'key'};

あなたの例から、彼女はコードです

        $filePath = __DIR__ . 'Your path ';
        $fileName = 'YourFilename.xml';

        if (file_exists($filePath . $fileName)) {
            $xml = simplexml_load_file($filePath . $fileName);
            $mainNode = $xml->{'code'};

            $cityArray = array();

            foreach ($mainNode as $key => $data)        {
               $cityArray[..] = $mainNode[$key]['cityCode'];
               ....

            }     

        }

3
そこに{}ハイフンのような特殊文字がない限り、使用する必要はありません。$xml->{'key'}は醜い書き方$xml->keyです。
IMSoP 2017

0
header("Content-Type: text/html; charset=utf8");
$url  = simplexml_load_file("http://URI.com");

 foreach ($url->PRODUCT as $product) {  
    foreach($urun->attributes() as $k => $v) {
        echo $k." : ".$v.' <br />';
    }
    echo '<hr/>';
}

2
この回答には説明が不足しているため、オブジェクトではなく文字列になるようにecho強制$vするという重要な洞察を見逃しています(string)$v
IMSoP 2017

0

この関数で配列を変換できます

function xml2array($xml){
$arr = array();

foreach ($xml->children() as $r)
{
    $t = array();
    if(count($r->children()) == 0)
    {
        $arr[$r->getName()] = strval($r);
    }
    else
    {
        $arr[$r->getName()][] = xml2array($r);
    }
}
return $arr;
}

できますが、なぜしたいのですか?
IMSoP 2017

インデックスが数値の場合、問題になる可能性があるためです。このように$ variable-> code-> 0?SimpleXMLElementオブジェクト([コード] =>配列([0] => SimpleXMLElementオブジェクト(...
nixis '30 / 11/17

<0>は有効なXMLタグではないため、これは決して起こりません。のようないくつかの有効なXML名は、有効なPHP名ではありません<foo-bar>が、->{'foo-bar'}構文で処理できます。または0、同様の名前付き要素のリストにあるth要素にアクセスするだけですか?それだけ$parent->childName[0]です。
IMSoP 2017年

0
$codeZero = null;
foreach ($xml->code->children() as $child) {
   $codeZero = $child;
}

$lat = null;
foreach ($codeZero->children() as $child) {
   if (isset($child->lat)) {
      $lat = $child->lat;
   }
}

私はこのコードスニペットを表示するようにしようとしているかわからないんだけど、それは非常にコンボリューション(間違った)書き込みの方法だように見えます$codeZero = $xml->code[0]$lat = $xml->code[0]->lat
IMSoP

@IMSoP、あなたはコードを試すことさえせずにこれに投票していますか?それがうまくいかなければ、私はそれを投稿しなかっただろう。あなたは、単純なforループよりもきれいなforeachを許可しないことを示唆しています。詳細はすべて覚えていませんが、他のソリューションではうまくいかなかったときにうまくいきました。
craned

それが何をしているかの説明がないので、私は主に反対票を投じました。読み返してもわからない場合は、他の人にとってどのように役立つと思いますか?foreachの使用に関しては、次のことが可能です。foreach ( $xml->code as $code ) { $lat = (string)$code->lat; echo $lat; }ただし、ここでループしているのは「最初の<code>要素のすべての子」です。私にはあまり意味がありません。明確にするため、$xml->code->children()はの省略形であり$xml->code[0]->children()、「呼ばれる子供」ではありませんcode
IMSoP 2017

@IMSoP、まあ、それは公平な点です。説明を提供する必要がありました。おそらくそれは当時は私にはあまりにも明白だったので、私には起こりませんでした。ただし、少なくとも私の考えでは、このページの誰もが既にコンテキストを知っており、何が起こっているのかをすでに知っているので説明は必要ないという事実です。これは、1人の人がすでに私の回答に賛成票を投じていること、または私が否定的であるという事実によって証明されています。将来はもっと説明を載せるようにします。
craned

また、私はあなたの提案を最初に試してみることをほぼ保証できますが、それがうまくいかなかったので、別の提案を見つける必要がありました。
craned

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.