将XML转换成JSON格式的PHP数组将删除某些元素上的属性

时间:2021-11-24 22:18:25

I'm currently processing an extensive XML file, to make some of the processing easier I've used the following method as mentioned extensively on stack overflow

我目前正在处理一个广泛的XML文件,以便使我在stack overflow上广泛提到的以下方法更容易处理

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

This has been awesome but going over my code I've noted some instances where attributes on certain elements aren't converting correctly, at this step $json = json_encode($xml);

这非常棒,但在我的代码中,我注意到一些实例,某些元素的属性不能正确转换,在这一步$json = json_encode($xml);

Here is a stripped down XML example.

下面是一个简化的XML示例。

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

and here is the output.

这是输出。

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

As seen above if the element contains any info on that exact node the associated attributes with that element are not processed. This is causing significant data loss between the conversion.

如上所示,如果元素包含关于该节点的任何信息,则不处理与该元素相关的属性。这在转换之间造成了重大的数据损失。

Does anyone know how to solve this issue?

有人知道怎么解决这个问题吗?

Thanks in advance!

提前谢谢!

1 个解决方案

#1


4  

The elements are processed, they are just not being displayed in the case where the node has attributes AND values. In that case, only the values are being displayed.

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

The json / array conversion you do is not taking that into account, and only keep the to-be displayed values. I'm afraid there is no trick to do that, but here is a function I used when I didn't know how to trickily convert SimpleXML elements (And which is handling the attributes and values separately)

您所做的json /数组转换没有考虑到这一点,只保留要显示的值。恐怕没有什么技巧可以做到这一点,但是这里有一个函数,当我不知道如何巧妙地转换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);

Output :

输出:

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"
      }
    }
  }
}

#1


4  

The elements are processed, they are just not being displayed in the case where the node has attributes AND values. In that case, only the values are being displayed.

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

The json / array conversion you do is not taking that into account, and only keep the to-be displayed values. I'm afraid there is no trick to do that, but here is a function I used when I didn't know how to trickily convert SimpleXML elements (And which is handling the attributes and values separately)

您所做的json /数组转换没有考虑到这一点,只保留要显示的值。恐怕没有什么技巧可以做到这一点,但是这里有一个函数,当我不知道如何巧妙地转换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);

Output :

输出:

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"
      }
    }
  }
}