SimpleXMLElement Nesnesinden değer al


198

Böyle bir şey var:

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

Geonames'den XML indirmesi gerekiyor. Eğer yaparsam 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
                )

Gördüğünüz gibi yapıyorum $xml->code[0]->latve bir nesne döndürüyor. Değeri nasıl alabilirim?



@kubas bir cevap seçebilir misin?
kqw

1
2017 Güncellemesi: SO artık en iyi cevabı en üstte göstermiyor. En iyi cevap burada .
rinogo

2
@rinogo Yanıt bloğunun üst kısmındaki sıralama sekmelerinden birini yanlışlıkla tıkladınız. Bağlantı verdiğiniz yanıt 345 oy içerir, bu nedenle "oylar" olarak ayarlanmışsanız en üstte gösterilir.
IMSoP

1
Teşekkürler @IMSoP! Haklısın - Bir noktada "aktif" i tıklamalıydım (eski cevapları olan eski sorular için yararlıdır, btw) - iyi biliyorum "oy" a değiştirmeliyim! :)
rinogo

Yanıtlar:


428

Bir dizeye simpleXML Nesnesi yayınlamanız gerekir.

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

10
Sadece xml nesnesini json_encode ve sonra json_decode eğer başa çıkmak için iç içe bir stdObject olsun, tembel ve basit yapıları ile çalışırken oldukça kullanışlı: D
Louis

1
aptalca bir soru, ama bu bir hata değil mi? bkz. php.net/simplexml#95762 neden bazı alanlara yazı yazmak zorunda değilsiniz, ancak bazılarında yazmak zorundasınız?
gcb

7
Bu cevap 2016'da hala popoları daha da zorluyor!
Hirdesh Vishwdewa

4
bunun çok karmaşık olduğuna inanamıyorum. neden "getValue" değil "getName" adlı bir sınıf yapsınlar? el ile (string) dönüştürmek yerine yazdırdıysanız neden boş dize yazdırdılar. NEDEN??
user151496

1
@ user151496 Teknik olarak, string dizisi size "değer" değil, "metin içeriği" veriyor. Ancak evet, özel olarak adlandırılmış bir yöntem daha keşfedilebilir olacaktır. Buna alıştıktan sonra, aslında kullanımı daha zor değildir .
IMSoP

92

__ToString () sihirli yöntemini de kullanabilirsiniz

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

5
Ya sprintfbirlikte %sformatında. Veya echove tamponlama çıktı, veya veya veya veya ...
hakre

Nesneyi PHP'de XML'ye nasıl dönüştürebilirim? @sglessard
Gem

17

XML öğesinin değerinin bir kayan sayı (enlem, boylam, mesafe) olduğunu biliyorsanız, şunu kullanabilirsiniz: (float)

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

Ayrıca, (int)tam sayı için:

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

16

eğer yok XML Unsuru değerini bilmek, kullanabilirsiniz

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

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

Değerin bir sayı olup olmadığını belirlemeniz gerektiğinde çalışır, çünkü (string)her zaman dize ve is_int($value)döndürürfalse


Boole için de kontrol etmenin herhangi bir yolu: (string) $ value == 'true' || (string) $ value == 'false'?
Talisin

12

Benim için dizileri kullanmak nesnelerden daha kolay,

Yani, bir Xml-Object dönüştürüyorum,

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

4
Gerçekten acele etmediğiniz sürece JSON'a ve sonra aynı bağlamda dönüştürmek inanılmaz derecede verimsizdir. Nesnelerle çalışmak zor değildir ve gerçekten dizileri tercih ediyorsanız , nesneyi yerel olarak bir diziye dönüştürmelisiniz.
William

1
İnsanların bunu neden yaptığını asla anlamıyorum - SimpleXML'in tüm özelliklerini atıyorsunuz, $xml['foo'][0]['bar'][0]['@attributes']['baz']bunun yerine yazabiliyorsunuz $xml->foo->bar['baz'].
IMSoP

2

Bu, xml ile ilgili değerleri diziye dönüştürmeme her zaman yardımcı olan işlevdir

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

    return $out;
}

Bu, diğer şeylerin yanı sıra atılacaktır veya bunlardan kopacaktır: herhangi bir nitelik, bir ad alanındaki herhangi bir şey, herhangi bir CDATA bloğu. Her şeyden önce SimpleXML'in size sunduğu kolaylık yöntemlerini kaybedebilirsiniz.
IMSoP

2

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

0 değerinin dizinin geçerli işaretçisinin altındaki öğeyi döndürür, böylece değer elde edersiniz


1

mülkünüze erişmek için '{}' kullanabilirsiniz ve sonra istediğiniz gibi yapabilirsiniz. Kaydedin veya içeriği görüntüleyin.

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

Örneğinizden onun kodu

        $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
İçinde {}tireler gibi özel karakterler olmadığı sürece kullanmaya gerek yoktur . $xml->{'key'}sadece daha çirkin bir yazım şeklidir $xml->key.
IMSoP

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
Bu cevap herhangi bir açıklamadan yoksundur ve bu nedenle , bir nesne yerine bir dize haline gelmeye echozorlayan anahtar anlayışı kaçırır . $v(string)$v
IMSoP

0

diziyi bu işlevle dönüştürebilirsiniz

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

Yapabilirsin, ama neden istiyorsun?
IMSoP

Çünkü dizin bir sayı ise, bir sorun olabilir. Bu $ değişken-> kod-> 0 gibi mi? SimpleXMLElement Nesnesi ([kod] => Dizi ([0] => SimpleXMLElement Nesnesi (...
nixis

<0>geçerli bir XML etiketi değil, bu yüzden asla olmaz. Birkaç geçerli XML adı, geçerli PHP adları değildir <foo-bar>, ancak ->{'foo-bar'}sözdizimi ile işlenebilir . Yoksa sadece 0benzer adlandırılmış öğeler listesindeki th öğesine erişmek mi istiyorsunuz ? Bu sadece $parent->childName[0].
IMSoP

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

Bu kod snippet'inin göstermeye çalıştığından emin değilim, ancak çok kıvrımlı (ve yanlış) bir yazı yolu gibi görünüyor $codeZero = $xml->code[0]ve$lat = $xml->code[0]->lat
IMSoP

@IMSoP, kodu denemeden oy kullanıyorsunuz? Eğer işe yaramazsa ben bunu yayınlamazdım. Öneriniz döngü için basit olandan daha temiz olan bir foreach'e izin vermiyorsunuz. Artık tüm detayları hatırlamıyorum, ancak diğer çözümler işe yaramadığında işe yaradı.
craned

Çoğunlukla oy kullandım çünkü ne yaptığına dair bir açıklaması yok. Tekrar okurken anlamasan bile, başka kimseye nasıl faydalı olması gerekiyordu? Bir foreach kullanmaya gelince, şunları yapabilirsiniz: foreach ( $xml->code as $code ) { $lat = (string)$code->lat; echo $lat; }Ama burada döngü yaptığınız şey "ilk <code>elementin tüm çocukları "; bu bana pek mantıklı gelmiyor. $xml->code->children()Açıklığa kavuşturmak, kısaca $xml->code[0]->children()"çağrılmış çocuklar" için değil code.
IMSoP

@IMSoP, Şey, bu adil bir nokta. Bir açıklama yapmalıydım; muhtemelen o zaman bana öyle açık görünüyordu ki o benim başıma gelmedi. Ancak, benim lehime, en azından, bu sayfadaki herkes bağlamı zaten biliyor ve bir açıklamaya gerek duymayacağı çünkü zaten ne olduğunu zaten biliyorlar. Bu, bir kişinin cevabımı daha önceden oyladığı ya da şimdi olumsuz olacağım gerçeği ile kanıtlanmıştır. Gelecekte bir açıklama yayınlamak için daha iyisini yapacağım.
craned

Ayrıca, ilk önce önerinizi denerdim ve neredeyse işe yaramayacağını garanti edebilirim, bu yüzden başka bir tane bulmak zorunda kaldım.
craned

-2
foreach($xml->code as $vals )
{ 
    unset($geonames);
    $vals=(array)$vals;
    foreach($vals as $key => $value)
      {
        $value=(array)$value;
        $geonames[$key]=$value[0];
      }
}
print_r($geonames);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.