从 SimpleXMLElement 对象中获取值

Posted

技术标签:

【中文标题】从 SimpleXMLElement 对象中获取值【英文标题】:Get value from SimpleXMLElement Object 【发布时间】:2011-02-21 11:50:40 【问题描述】:

我有这样的事情:

$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 下载 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,它返回一个对象。我怎样才能获得价值?

【问题讨论】:

Forcing a SimpleXML Object to a string, regardless of context 的可能重复项 2017 更新:SO 不再在顶部显示最佳答案。 The best answer is here. @rinogo 您可能不小心单击了答案块顶部的排序选项卡之一。您链接到的答案有 345 票,因此如果您将排序设置为“投票”,则显示在顶部。 谢谢,@IMSoP!你是对的 - 我一定在某个时候点击了“活动”(对于旧问题的答案过时有用,顺便说一句) - 很高兴知道我需要将它改回“投票”! :) 【参考方案1】:

您必须将 simpleXML 对象转换为字符串。

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

【讨论】:

刚刚注意到如果你对 xml 对象进行 json_encode 然后 json_decode 它你会得到一个嵌套的 stdObject 来处理,当你懒惰和使用简单的结构时非常方便:D 愚蠢的问题,但这不是错误吗?请参阅php.net/simplexml#95762 为什么您不必在某些字段上强制转换类型,而在其他字段上却必须? 这个答案在 2016 年仍然会更加激烈! 我不敢相信这是这么复杂。为什么他们会创建一个名为“getName”而不是“getValue”的类?如果您打印它而不是手动将其转换为(字符串),他们为什么会打印空字符串。为什么?? @user151496 从技术上讲,字符串转换不是给你“价值”,而是“文本内容”。但是,是的,一个专门命名的方法会更容易被发现。但是,一旦您习惯了这一点,它实际上并不难使用【参考方案2】:

你也可以使用魔术方法__toString()

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

【讨论】:

sprintf%s 格式。或echo 和输出缓冲,或或或或... 如何在 PHP 中将对象转换为 XML? @sglessard @Gem 你可能想要某种序列化 - 见***.com/questions/137021/php-object-as-xml-document【参考方案3】:

如果知道XML元素的值是浮点数(纬度、经度、距离),可以使用(float)

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

另外,(int) 表示整数:

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

【讨论】:

【参考方案4】:

如果你知道 XML Element 的值,你可以使用

$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' || (string)$value == 'false'? 请注意,这并不总是正确的。它仅对具有自然(正)整数的字符串有效。所以,它们必须在一个字符串中。它们不能是浮点数或负数,因为小数分隔符、减号等将被评估为假。所以,ctype_digitpreg_match('/^\d+$/', $var) 如果你想检查它是否是一个数值,包括浮点数和否定,请改用is_numeric()。【参考方案5】:

对我来说,数组比对象更容易使用,

所以,我转换了一个 Xml-Object,

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

【讨论】:

转换为 JSON 然后返回相同的上下文是非常低效的,除非你真的很着急。使用对象并不难,如果你真的更喜欢数组,你应该将对象原生地转换为数组。 我不明白为什么人们会这样做——你抛弃了 SimpleXML 的所有功能,只是为了写 $xml['foo'][0]['bar'][0]['@attributes']['baz'] 而不是 $xml->foo->bar['baz']【参考方案6】:

这是一直帮我把xml相关的值转换成数组的函数

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

    return $out;

【讨论】:

这将丢弃或中断,其中包括:任何属性、命名空间中的任何内容、任何 CDATA 块。这一切只是为了让您失去 SimpleXML 最初为您提供的便利方法。【参考方案7】:

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

它返回数组当前指针下的元素,为0,所以你会得到值

【讨论】:

【参考方案8】:

您可以使用“”来访问您的属性,然后您可以随心所欲地进行操作。 保存或显示内容。

    $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'];
               ....

                 

        

【讨论】:

没有必要使用,除非其中有连字符等特殊字符。 $xml->'key' 只是写 $xml->key 的一种更丑陋的方式。【参考方案9】:
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/>';

【讨论】:

这个答案没有任何解释,因此错过了echo 强制$v 成为字符串而不是对象的关键见解,就像(string)$v 一样。【参考方案10】:

你可以用这个函数转换数组

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;

【讨论】:

可以,但为什么要这样做? 因为如果index是一个数字,可能会出问题。像这样 $variable->code->0 ? SimpleXMLElement 对象 ( [code] => 数组 ( [0] => SimpleXMLElement 对象 (... &lt;0&gt; 不是一个有效的 XML 标签,所以这永远不会发生。一些有效的 XML 名称不是有效的 PHP 名称,例如 &lt;foo-bar&gt;,但可以使用 -&gt;'foo-bar' 语法处理。或者您的意思是访问类似命名元素列表中的0th 元素?那只是$parent-&gt;childName[0]【参考方案11】:
$codeZero = null;
foreach ($xml->code->children() as $child) 
   $codeZero = $child;


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

【讨论】:

我不确定这段代码 sn-p 试图显示什么,但看起来这是一种非常复杂(且错误)的写法 $codeZero = $xml-&gt;code[0]$lat = $xml-&gt;code[0]-&gt;lat @IMSoP,您甚至没有尝试代码就投了反对票?如果它不起作用,我就不会发布它。您的建议不允许使用 foreach,这比简单的 for 循环更干净。我不记得所有细节了,但是当其他解决方案不记得时它起作用了。 我投了反对票,主要是因为它没有解释它在做什么。如果你读回来的时候连你都看不懂,那它对别人有什么用呢?至于使用 foreach,当然可以:foreach ( $xml-&gt;code as $code ) $lat = (string)$code-&gt;lat; echo $lat; 但是你在这里循环的是“第一个 &lt;code&gt; 元素的所有子元素”;这对我来说没有多大意义。澄清一下,$xml-&gt;code-&gt;children()$xml-&gt;code[0]-&gt;children() 的简写,而不是“称为code 的孩子”。 @IMSoP,嗯,这是一个公平的观点。我应该提供一个解释;当时对我来说这似乎很明显,以至于我没有想到。然而,至少对我有利的是,这个页面上的任何人都已经知道上下文并且不需要解释,因为他们已经知道发生了什么。一个人已经对我的答案投了赞成票,否则我现在会反对这一事实证明了这一点。以后我会更好地发布解释。 另外,我几乎可以保证我会先尝试您的建议,但没有奏效,所以我不得不另找一个。【参考方案12】:
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);

【讨论】:

以上是关于从 SimpleXMLElement 对象中获取值的主要内容,如果未能解决你的问题,请参考以下文章

获取 SimpleXMLElement 的 XML 内容

使用xml php中的属性获取值

PHP中SimpleXMLElement对象字符编码

从PHP SimpleXMLElement中提取数组

SimpleXMLElement 在 addChild 和 addAttribute 中处理文本值的基本原理

如何删除SimpleXMLElement对象中的[@attributes]