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

1
2017 업데이트 : SO가 더 이상 최고의 답변을 표시하지 않습니다. 가장 좋은 대답은 여기 입니다.
rinogo

2
@rinogo 실수로 답변 블록의 상단에있는 정렬 탭 중 하나를 클릭했을 수 있습니다. 링크 된 답변은 345 표이므로 정렬이 "투표"로 설정된 경우 맨 위에 표시됩니다.
IMSoP

1
감사합니다, @IMSoP! 당신이 옳습니다-어느 시점에서 "활성"을 클릭 했어야합니다. :)
rinogo

답변:


426

simpleXML 오브젝트를 문자열로 캐스트해야합니다.

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

9
xml 객체를 json_encode 한 다음 json_decode하면 중첩 된 stdObject를 가져 와서 게으르고 간단한 구조로 작업 할 때 매우 편리합니다. : D
Louis

1
바보 같은 질문이지만 그게 버그가 아닙니까? 참조 php.net/simplexml#95762을 당신이 어떤 분야에 캐스트 입력 할 필요가 없습니다 그러나 다른 사람에 당신이 왜?
gcb

7
이 답변은 2016 년에도 여전히 꽁초를 쫓고 있습니다!
Hirdesh Vishwdewa

4
나는 이것이 너무 복잡하다는 것을 믿을 수 없다. 왜 그들은 "getName"이 아닌 "getName"이라는 클래스를 만들까요? 왜 수동으로 (문자열)로 변환하지 않고 인쇄하면 빈 문자열이 인쇄됩니까? 왜??
user151496

1
@ user151496 기술적으로 문자열 캐스트는 "값"이 아니라 "텍스트 내용"을 제공합니다. 그러나 그렇습니다. 특별히 명명 된 방법이 더 발견 가능합니다. 그러나 이것에 익숙해지면 실제로 사용 하기가 더 이상 어렵지 않습니다 .
IMSoP

90

매직 메소드 __toString ()을 사용할 수도 있습니다.

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

5
또는 sprintf%s형식입니다. 또는 echo출력 버퍼링, 또는 또는 또는 또는 ...
hakre

PHP에서 객체를 XML로 변환하려면 어떻게해야합니까? @sglessard
보석

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'|| (문자열) $ value == 'false'?
Talisin 2016 년

12

나를 위해 객체보다 배열을 사용하는 것이 더 쉽습니다.

Xml-Object를 변환합니다.

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

3
실제로 서두르지 않는 한 JSON으로 변환 한 다음 동일한 컨텍스트에서 다시 변환하는 것은 엄청나게 비효율적입니다. 객체로 작업하는 것은 어렵지 않으며 실제로 배열을 선호하는 경우 객체를 기본적으로 배열로 변환해야합니다.
William

사람들이 왜 이것을하는지 이해하지 못합니다. 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

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

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

인덱스가 숫자이면 문제가 될 수 있습니다. 이 $ variable-> code-> 0처럼? SimpleXMLElement 객체 ([code] => 배열 ([0] => SimpleXMLElement 객체 (...
nixis

<0>유효한 XML 태그가 아니므로 절대 발생하지 않습니다. 유효한 일부 XML 이름은와 같은 유효한 PHP 이름이 <foo-bar>아니지만 ->{'foo-bar'}구문 으로 처리 할 수 ​​있습니다 . 아니면 0비슷한 명명 된 요소 목록에서 th 요소에 액세스하는 것을 의미 합니까? 그저 $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를 허용하지 않는다고 제안합니다 .foreach는 단순한 for 루프보다 깨끗합니다. 더 이상 모든 세부 사항을 기억하지는 않지만 다른 솔루션이 그렇지 않을 때 작동했습니다.
크레인

나는 그것이 무엇을하고 있는지에 대한 설명이 없기 때문에 주로 투표를 거부했습니다. 당신이 그것을 읽을 때 그것을 이해하지 못한다면, 그것은 다른 사람에게 어떻게 유용해야합니까? foreach를 사용하는 경우 다음을 수행 할 수 있습니다. foreach ( $xml->code as $code ) { $lat = (string)$code->lat; echo $lat; }그러나 여기서 반복하는 것은 "첫 번째 <code>요소 의 모든 자식 "입니다. 그것은 나에게별로 이해가되지 않습니다. 명확하게하기 위해 "자식 호출자 "가 아닌 $xml->code->children()속기입니다 . $xml->code[0]->children()code
IMSoP

@IMSoP, 글쎄요, 그건 좋은 지적입니다. 나는 설명을했을 것이다. 아마 나에게 그렇게되지 않았을 때 그것은 나에게 너무 분명해 보였다. 그러나, 적어도이 페이지에있는 사람은 이미 상황을 알고 있으며 어떤 일이 일어나고 있는지 이미 알고 있기 때문에 설명이 필요하지 않다는 사실이 필자에게 유리합니다. 이것은 한 사람이 이미 내 대답에 찬성 투표했거나 지금은 부정적이라는 사실에 의해 입증됩니다. 앞으로 설명을 게시하는 것이 좋습니다.
크레인

또한, 나는 당신의 제안을 먼저 시도했을 것이라고 거의 보장 할 수 있으며, 효과가 없었으므로 다른 것을 찾아야했습니다.
크레인

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