使用 JSON 将 XML 转换为 PHP 数组正在删除某些元素的属性

Posted

技术标签:

【中文标题】使用 JSON 将 XML 转换为 PHP 数组正在删除某些元素的属性【英文标题】:Converting XML into PHP array with JSON is deleting attributes on some elements 【发布时间】:2014-10-30 03:41:16 【问题描述】:

我目前正在处理一个扩展的 XML 文件,为了使某些处理更容易,我使用了以下在堆栈溢出中广泛提到的方法

$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

这太棒了,但是在查看我的代码时,我注意到某些情况下某些元素的属性没有正确转换,在这一步 $json = json_encode($xml);

这是一个精简的 XML 示例。

<?xml version="1.0"?>
<property>
    <landDetails>
        <area unit="squareMeter"/>
    </landDetails>
    <buildingDetails>
        <area unit="squareMeter">100</area>
    </buildingDetails>
</property>

这是输出。

Array (
    [landDetails] => Array (
        [area] => Array (
            [@attributes] => Array (
                [unit] => squareMeter
            )
        )
    )
    [buildingDetails] => Array (
        [area] => 100
    )
)

如上所示,如果元素包含有关该确切节点的任何信息,则不会处理与该元素关联的属性。这会导致转换之间的大量数据丢失。

有人知道如何解决这个问题吗?

提前致谢!

【问题讨论】:

【参考方案1】:

元素被处理,它们只是在节点具有属性和值的情况下不显示。在这种情况下,仅显示值。

您所做的 json / array 转换没有考虑到这一点,只保留要显示的值。恐怕没有什么技巧可以做到这一点,但这是我在不知道如何巧妙地转换 SimpleXML 元素时使用的一个函数(并且分别处理属性和值)

function simplexml_to_array ($xml, &$array) 

  // Empty node : <node></node>
  $array[$xml->getName()] = '';

  // Nodes with children
  foreach ($xml->children() as $child) 
    simplexml_to_array($child, $array[$xml->getName()]);
  

  // Node attributes
  foreach ($xml->attributes() as $key => $att) 
      $array[$xml->getName()]['@attributes'][$key] = (string) $att;
  

  // Node with value
  if (trim((string) $xml) != '') 
    $array[$xml->getName()][] = (string) $xml; 
  



$xml = simplexml_load_string($xml);
simplexml_to_array($xml, $arr);
var_dump($arr);

输出:

array(1) 
  ["property"]=>
  array(2) 
    ["landDetails"]=>
    array(1) 
      ["area"]=>
      array(1) 
        ["@attributes"]=>
        array(1) 
          ["unit"]=>
          string(11) "squareMeter"
        
      
    
    ["buildingDetails"]=>
    array(1) 
      ["area"]=>
      array(2) 
        ["@attributes"]=>
        array(1) 
          ["unit"]=>
          string(11) "squareMeter"
        
        [0]=>
        string(3) "100"
      
    
  

【讨论】:

只是多看一点,上面的代码似乎没有在前两个 xml 子元素上传递一个属性数组?例如,如果您在property 上添加color="red" 属性,然后在landDetailsbuildingDetails 上添加color="green" 属性以及在area 上添加color="blue" 属性,则使用上述XML。只有蓝色属性将被导出到后续数组中。 @DevonMather 对,我不知道为什么这个 foreach 循环在 has_children 检查中。事实上,这个 has_children 检查是不需要的。我发现 SimpleXML 返回一个带有空格和换行符的字符串。 trim 足以检测它是否没有实际值。我在几个不同的 XML 结构上尝试了这个新代码,现在看起来没问题。 :) 此代码似乎不起作用。 &lt;xml&gt; &lt;node1 attr1="111" attr2="222"&gt; &lt;node2 attr3="aaa" attr4="bbb"&gt;&lt;/node2&gt; &lt;node2 attr3="ccc" attr4="ddd"&gt;xxx&lt;/node2&gt; &lt;/node1&gt; &lt;/xml&gt; 这里aaabbb 不会出现在输出中。

以上是关于使用 JSON 将 XML 转换为 PHP 数组正在删除某些元素的属性的主要内容,如果未能解决你的问题,请参考以下文章

XML 到 JSON 或数组? PHP

在 PHP 中将 JSON 转换为 XML,但在 XML 中为 JSON 数组创建一个容器元素

php将xml转换为数组

如何使用 XSLT 将单个子 xml 元素转换为 Json 数组

将单个xml节点作为数组转换为json

当有一个孩子时,PHP将XML转换为JSON组