2

由于 Zend_Rest_Client_Result 对象,我有一个像这样的简单 xml 对象。

<userdetails>
  <name value="jake"/>
  <type value="user"/>
  <attribute name="fname">
    <value>Jake</value>
  </attribute>
  <attribute name="lname">
    <value>Gordon</value>
  </attribute>
  <attribute name="phone">
    <value>123-555-1234</value>
    <value>999-888-7777</value> 
  </attribute>
 </userdetails>

如何使用 PHP 从上述 XML 对象创建这样的数组?

 $userDetails = array();
 $userDetails["name"] = "jake";
 $userDetails["type"] = "user";
 $userDetails["fname"] = "Jake";
 $userDetails["lname"] = "Gordon";
 $userDetails["phone"][0] = "123-555-1234";
 $userDetails["phone"][1] = "123-555-1234";

谢谢,

4

2 回答 2

1
$xml = '<userdetails><name value="jake"/><type value="user"/><attribute name="fname"><value>Jake</value></attribute><attribute name="lname"><value>Gordon</value></attribute><attribute name="phone"><value>123-555-1234</value><value>999-888-7777</value></attribute></userdetails>';

$simple = new SimpleXMLElement($xml);
$array = array();

if(isset($simple->name))
  $array['name'] = (string) $simple->name->attributes()->value;

if(isset($simple->type))
  $array['type'] = (string) $simple->type->attributes()->value;

if($foreach = $simple->xpath('//attribute[@name="fname"]/value'))
{
  foreach($foreach as $node)
  {
    $array['fname'] = (string) $node;
  }
}

if($foreach = $simple->xpath('//attribute[@name="lname"]/value'))
{
  foreach($foreach as $node)
  {
    $array['lname'] = (string) $node;
  }
}

if($foreach = $simple->xpath('//attribute[@name="phone"]/value'))
{
  $array['phone'] = array();
  foreach($simple->xpath('//attribute[@name="phone"]/value') as $node)
  {
    $array['phone'][] = (string) $node;
  }
}

print_r($array);
于 2012-09-07T05:28:19.347 回答
0
function xmlstr_to_array($xmlstr) {
  $doc = new DOMDocument();
  $doc->loadXML($xmlstr);
  return domnode_to_array($doc->documentElement);
}

function domnode_to_array($node) {
  $output = array();
  switch ($node->nodeType) {
   case XML_CDATA_SECTION_NODE:
   case XML_TEXT_NODE:
    $output = trim($node->textContent);
   break;
   case XML_ELEMENT_NODE:
    for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {
     $child = $node->childNodes->item($i);
     $v = domnode_to_array($child);
     if(isset($child->tagName)) {
       $t = $child->tagName;
       if(!isset($output[$t])) {
        $output[$t] = array();
       }
       $output[$t][] = $v;
     }
     elseif($v) {
      $output = (string) $v;
     }
    }
    if(is_array($output)) {
     if($node->attributes->length) {
      $a = array();
      foreach($node->attributes as $attrName => $attrNode) {
       $a[$attrName] = (string) $attrNode->value;
      }
      $output['@attributes'] = $a;
     }
     foreach ($output as $t => $v) {
      if(is_array($v) && count($v)==1 && $t!='@attributes') {
       $output[$t] = $v[0];
      }
     }
    }
   break;
  }
  return $output;
}
?>

另一种快速而肮脏的方法是:

<?php
  $a = json_decode(json_encode((array) simplexml_load_string($s)),1);
?>

这不太健壮,并且会在您编写包含 CDATA 节点的代码时产生问题。

于 2012-09-07T05:19:46.803 回答