รับค่าจากวัตถุ SimpleXMLElement


198

ฉันมีสิ่งนี้:

$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

1
2017 อัปเดต: ดังนั้นจะไม่แสดงคำตอบที่ดีที่สุดอีกต่อไป คำตอบที่ดีที่สุดอยู่ที่นี่
rinogo

2
@rinogo คุณอาจคลิกแท็บการเรียงลำดับที่ด้านบนสุดของบล็อกคำตอบโดยไม่ตั้งใจ คำตอบที่คุณเชื่อมโยงมี 345 คะแนนดังนั้นจะปรากฏที่ด้านบนหากคุณเรียงลำดับเป็น "โหวต"
IMSoP

1
ขอบคุณ @IMSoP! คุณถูกต้อง - ฉันต้องคลิก "ใช้งาน" ในบางจุด (มีประโยชน์สำหรับคำถามเก่าที่มีคำตอบที่ล้าสมัย btw) - ดีที่ฉันรู้ว่าฉันต้องเปลี่ยนกลับเป็น "โหวต"! :)
rinogo

คำตอบ:


428

คุณต้องใช้ SimpleXML Object เป็นสตริง

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

10
เพิ่งสังเกตว่าคุณ json_encode วัตถุ xml แล้ว json_decode คุณจะได้รับ stdObject ที่ซ้อนกันเพื่อจัดการกับมันค่อนข้างมีประโยชน์สำหรับเมื่อคุณขี้เกียจและทำงานกับโครงสร้างที่เรียบง่าย: D
Louis

1
คำถามงี่เง่า แต่นั่นไม่ใช่ข้อผิดพลาดหรือไม่? ดูphp.net/simplexml#95762ทำไมคุณไม่จำเป็นต้องพิมพ์ในบางฟิลด์ แต่ต้องทำกับคนอื่นด้วย
gcb

7
คำตอบนี้ยังคงเตะก้นได้ยากขึ้นในปี 2559!
Hirdesh Vishwdewa

4
ฉันไม่อยากจะเชื่อเลยว่ามันซับซ้อนเกินไป เหตุใดพวกเขาจึงสร้างคลาสที่ชื่อ "getName" แต่ไม่ใช่ "getValue" ทำไมพวกเขาจะพิมพ์สตริงที่ว่างเปล่าถ้าคุณพิมพ์แทนการแปลงด้วยตนเองเป็น (สตริง) ทำไม??
user151496

1
@ user151496 โดยทางเทคนิคแล้วการส่งสตริงไม่ได้ให้คุณค่า "แก่คุณ" แต่เป็น "เนื้อหาข้อความ" แต่ใช่วิธีที่มีชื่อเฉพาะจะสามารถค้นพบได้มากขึ้น เมื่อคุณได้รับใช้ในการนี้แม้ว่ามันไม่ได้จริง ๆ ยากที่จะใช้
IMSoP

92

นอกจากนี้คุณยังสามารถใช้วิธีเวทมนต์ __toString ()

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

5
หรือsprintfด้วย%sรูปแบบ หรือechoและบัฟเฟอร์ออกหรือหรือหรือ ...
hakre

ฉันจะแปลงวัตถุเป็น XML ใน PHP ได้อย่างไร @sglessard
อัญมณี

17

หากคุณรู้ว่าค่าขององค์ประกอบ XML เป็นจำนวนลอยตัว (ละติจูด, ลองจิจูด, ระยะทาง) คุณสามารถใช้ (float)

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

นอกจากนี้(int)สำหรับจำนวนเต็ม:

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

16

หากคุณไม่ทราบคุณค่าขององค์ประกอบ 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


วิธีใดก็ตามที่จะตรวจสอบบูลีนนอกเหนือจาก: (สตริง) $ value == 'true' || (สตริง) $ value == 'false'?
Talisin

12

สำหรับฉันมันง่ายกว่าการใช้อาร์เรย์มากกว่าวัตถุ

ดังนั้นฉันจึงแปลง Xml-Object

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

4
การแปลงเป็น JSON และกลับมาในบริบทเดียวกันนั้นไม่มีประสิทธิภาพอย่างไม่น่าเชื่อเว้นแต่คุณจะรีบ การทำงานกับวัตถุที่ไม่ยากและถ้าคุณจริงๆต้องการอาร์เรย์คุณควรจะแปลงวัตถุไปยังอาร์เรย์กำเนิด
วิลเลียม

1
ฉันไม่เคยเข้าใจว่าทำไมคนทำนี้ - คุณโยนออกไปคุณลักษณะทั้งหมดของ SimpleXML เพียงเพื่อให้คุณสามารถเขียนแทน$xml['foo'][0]['bar'][0]['@attributes']['baz'] $xml->foo->bar['baz']
IMSoP

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

2

ลอง 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

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

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

เพราะถ้าดัชนีเป็นตัวเลขมันอาจจะเป็นปัญหา ชอบ $ $ -> code-> 0 หรือไม่ วัตถุ SimpleXMLElement ([code] => Array ([0] => วัตถุ SimpleXMLElement (...
nixis

<0>ไม่ใช่แท็ก XML ที่ถูกต้องดังนั้นจะไม่มีวันเกิดขึ้นอีก ชื่อ XML ที่ถูกต้องบางชื่อไม่ใช่ชื่อ PHP ที่ถูกต้องเช่น<foo-bar>แต่สามารถจัดการกับ->{'foo-bar'}ไวยากรณ์ได้ หรือคุณแค่หมายถึงการเข้าถึง0องค์ประกอบที่สามในรายการองค์ประกอบที่มีชื่อคล้ายกัน? $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;
   }
}

ฉันไม่แน่ใจว่าข้อมูลโค้ดนี้พยายามที่จะแสดงอะไร แต่ดูเหมือนว่ามันเป็นวิธีการเขียนที่ซับซ้อน (และผิด) $codeZero = $xml->code[0]และ$lat = $xml->code[0]->lat
IMSoP

@IMSoP คุณลงคะแนนนี้โดยไม่ลองใช้รหัสเลยเหรอ? ฉันจะไม่โพสต์ไว้หากไม่ได้ผล ข้อเสนอแนะของคุณไม่อนุญาตให้ foreach ซึ่งสะอาดกว่าลูปแบบง่าย ฉันจำรายละเอียดทั้งหมดไม่ได้อีกต่อไป แต่ทำงานได้เมื่อไม่มีวิธีแก้ไขปัญหาอื่น
craned

ฉันลงคะแนนส่วนใหญ่เพราะไม่มีคำอธิบายเกี่ยวกับสิ่งที่ทำ แม้ว่าคุณจะไม่เข้าใจเมื่อคุณอ่านมันควรจะเป็นประโยชน์กับคนอื่นอย่างไร? สำหรับการใช้ foreach คุณสามารถทำได้: foreach ( $xml->code as $code ) { $lat = (string)$code->lat; echo $lat; }แต่สิ่งที่คุณวนลูปตรงนี้คือ "ลูกทั้งหมดของ<code>องค์ประกอบแรก"; ซึ่งไม่สมเหตุสมผลสำหรับฉัน ในการชี้แจง$xml->code->children()ก็คือจดชวเลข$xml->code[0]->children()ไม่ใช่ "ลูกที่เรียกว่าcode"
IMSoP

@ IMSoP ดีนั่นคือจุดยุติธรรม ฉันควรจะให้คำอธิบาย; มันอาจดูเหมือนชัดเจนสำหรับฉันในเวลาที่มันไม่ได้เกิดขึ้นกับฉัน อย่างน้อยที่สุดก็คือความจริงที่ว่าใครก็ตามที่อยู่ในหน้านี้รู้บริบทแล้วและไม่ต้องการคำอธิบายเพราะพวกเขารู้แล้วว่าเกิดอะไรขึ้น นี่เป็นข้อพิสูจน์โดยความจริงที่ว่ามีคนหนึ่งโหวตคำตอบของฉันไว้แล้วหรือตอนนี้ฉันจะติดลบ ฉันจะทำสิ่งที่ดีกว่าในการโพสต์คำอธิบายในอนาคต
craned

นอกจากนี้ฉันเกือบจะรับประกันได้ว่าฉันจะได้ลองข้อเสนอแนะของคุณก่อนและมันไม่ทำงานดังนั้นฉันจึงต้องค้นหาอีกครั้ง
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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.