【问题标题】:In XML to PHP array not getting keys在 XML 到 PHP 数组中没有得到键
【发布时间】:2015-05-23 12:45:36
【问题描述】:

我的服务器代码是这样的:

<?php
    $xml_data='<Player uID="p59936">
        <Name>Wojciech Szczesny</Name>
        <Position>Goalkeeper</Position>
        <Stat Type="first_name">Wojciech</Stat>
        <Stat Type="last_name">Szczesny</Stat>
        <Stat Type="birth_date">1990-04-18</Stat>
        <Stat Type="birth_place">Warszawa</Stat>
        <Stat Type="first_nationality">Poland</Stat>
        <Stat Type="weight">84</Stat>
        <Stat Type="height">196</Stat>
        <Stat Type="jersey_num">1</Stat>
        <Stat Type="real_position">Goalkeeper</Stat>
        <Stat Type="real_position_side">Unknown</Stat>
        <Stat Type="join_date">2008-07-01</Stat>
        <Stat Type="country">Poland</Stat>
        </Player>';
    $xml = simplexml_load_string($xml_data); 
    $array = json_decode(json_encode($xml),true);
    echo "<pre>";print_r($array);exit;
?>

但现在我得到的结果如下:

Array
(
    [@attributes] => Array
        (
            [uID] => p59936
        )

    [Name] => Wojciech Szczesny
    [Position] => Goalkeeper
    [Stat] => Array
        (
            [0] => Wojciech
            [1] => Szczesny
            [2] => 1990-04-18
            [3] => Warszawa
            [4] => Poland
            [5] => 84
            [6] => 196
            [7] => 1
            [8] => Goalkeeper
            [9] => Unknown
            [10] => 2008-07-01
            [11] => Poland
        )

)

所以不是像first_namelast_name这样的键,我得到像0,1,2...这样的键

那么如何获取XML中指定的key呢?

【问题讨论】:

    标签: php xml


    【解决方案1】:

    首先,您实际上不需要对其进行 json_encode/decode。你已经可以使用SimpleXML 来遍历你想要的那些值了。

    print_r 具有误导性,您会认为在转储之后,那些 Type 属性丢失了,但它们仍然存在。这是讨论该问题的eloquent answer

    但是如果你想得到这些值,你可以这样做(注意有很多方法可以得到):

    $xml = simplexml_load_string($xml_data);
    foreach($xml->Stat as $stat) {
        $type = (string) $stat->attributes()->Type;
        $node_value = (string) $stat;
        echo "$type: $node_value <br/>";
    }
    

    Sample Output

    【讨论】:

    【解决方案2】:

    缺少属性的原因是json_encode。当你仔细观察它时,你会发现,编码吞噬了属性Type

    $json = json_encode($xml);
    print_r($json);
    

    会显示

    {"@attributes":{"uID":"p59936"},"Name":"Wojciech Szczesny","Position":"守门员","Stat":["Wojciech","Szczesny"," 1990-04-18","华沙","波兰","84","196","1","守门员","未知","2008-07-01","波兰"]}

    另请参阅comment 手册页上的 comment

    但正如@Ghost 已经指出的那样,属性仍然存在于$xml 中,可以检查。

    【讨论】:

      【解决方案3】:

      这可以通过更改json_serialize 上的对象行为来实现,例如通过查找标记名然后更改返回的数据:

      class MyJson extends SimpleXMLElement implements JsonSerializable
      {
      
          public function jsonSerialize() {
              $name = $this->getName();
      
              if ($name !== 'Player') {
                  return $this;
              }
      
              $data = [];
              foreach ($this as $name => $element) {
                  if ($name === 'Stat') {
                      $name = (string) $element['Type'];
      
                  }
                  $data[$name] = (string) $element;
              }
      
              return $data;
          }
      }
      
      $xml = simplexml_load_string($buffer, 'MyJson');
      $array = json_decode(json_encode($xml), true);
      print_r($array);
      

      这会产生以下输出:

      Array
      (
          [Name] => Wojciech Szczesny
          [Position] => Goalkeeper
          [first_name] => Wojciech
          [last_name] => Szczesny
          [birth_date] => 1990-04-18
          [birth_place] => Warszawa
          [first_nationality] => Poland
          [weight] => 84
          [height] => 196
          [jersey_num] => 1
          [real_position] => Goalkeeper
          [real_position_side] => Unknown
          [join_date] => 2008-07-01
          [country] => Poland
      )
      

      另一种方法是在将文档序列化为 JSON(然后返回数组)之前对其进行修改。

      以下示例将所有&lt;Stat&gt; 元素转换为以Type 属性命名的元素,该属性包含原始&lt;Stat&gt; 元素的值。然后删除 &lt;Stat&gt; 元素:

      $xml = simplexml_load_string($buffer);
      foreach ($xml->xpath("//Player/Stat") as $stat) {
          $parent = $stat->xpath('..')[0];
          $parent->addChild((string) $stat["Type"])[0] = trim($stat);
          unset($stat[0]);
      }
      
      $array = json_decode(json_encode($xml), true);
      print_r($array);
      

      此示例产生以下输出:

      Array
      (
          [@attributes] => Array
              (
                  [uID] => p59936
              )
      
          [Name] => Wojciech Szczesny
          [Position] => Goalkeeper
          [first_name] => Wojciech
          [last_name] => Szczesny
          [birth_date] => 1990-04-18
          [birth_place] => Warszawa
          [first_nationality] => Poland
          [weight] => 84
          [height] => 196
          [jersey_num] => 1
          [real_position] => Goalkeeper
          [real_position_side] => Unknown
          [join_date] => 2008-07-01
          [country] => Poland
      )
      

      这只是两个例子。两者都可以创建相同的输出,它只是显示了两个不同的位置,您可以在其中放置逻辑以转换文档。

      相关资源:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-17
        • 1970-01-01
        • 2012-08-22
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多