json_encode()删除属性(PHP)

时间:2016-09-13 15:15:37

标签: php json xml simplexml

我在PHP 7.0.10中使用json_encode(simplexml_load_string($xml))将一些XML代码转换为JSON。以下XML

<?xml version="1.0" encoding="UTF-8"?>
<comments count="6">
<comment id="1" active="1" object="1" user="1" created="1473776866" updated="1473776866">Something</comment>
<comment id="2" active="1" object="1" user="2" created="1473776866" updated="1473776866">Hello</comment>
<comment id="3" active="1" object="1" user="3" created="1473776866" updated="1473776866">Just a comment</comment>
<comment id="6" active="0"/>
</comments>

创建以下结果:

{"comments":{"@attributes":{"count":"6"},"comment":    
["Something","Hello","Just a comment", {"@attributes":{"id":"6","active":"0"}}]}}

有人能解释一下<comment> s的所有属性发生了什么吗?

谢谢,我感谢任何帮助!

编辑:我发现只要给定节点只有文本值{... 1}},就会删除XML元素的所有属性。 所以目前我正在使用一个丑陋的解决方法:我已经修改了代码,以便在将XML提供给<something attribute="will be dropped">just text</something>之前用<text>string</text>替换所有字符串出现。这个解决方案目前工作正常,但我仍然对一个更干净的人感兴趣......

2 个答案:

答案 0 :(得分:0)

您的json输出显示最后一条评论的最后一个ID。所以json_encode()覆盖每次迭代的“注释”。您必须先准备好xml数据,然后才能将其提交给json_decode()。因此,将XML解析为Object simplexml,然后从中创建一个php数组,这样就可以encode该数组。我不认为你在这里得到单线解决方案;)

问题: 有人可以用评论的所有属性向我解释发生了什么吗?

不缺少attributes,来自1-5的<comment>不会出现在json中。

更新:Sry,没有看到这部分"Something","Hello","Just a comment",,这真的很有线。所有的评论都在那里,但在同一个数组中是属性!?!?属性本身就是一个对象!? 你必须像我上面所说的那样自己做好准备。没办法。你不能从json_encode(simpelxml_load_string('XML'))中删除结果,而不是为此做出了SimpleXML!

答案 1 :(得分:0)

SimpleXML不是为这种盲转换而构建的。它不会创建一个可以转换为JSON的整洁数组,并且实际上创建一个巧妙地封装XML的所有可能结构的JSON格式是棘手的(并且恕我直言相当无意义)。

当你像这样运行json_encode时调用的方法主要用于调试(注意@attributes不是你在与对象本身交互时使用的东西。)

这里的具体问题是,它试图通过选择如何最好地表示每个元素的内容来提供帮助,例如a)只是一个字符串,b)一个子元素数组,c)一个带有'@的对象attributes'属性包含属性键值对等。它没有包含字符串内容和属性的格式,因此您不能同时获得输出。

解决方案as JustOnUnderMillions rightly says是将您实际想要的数据解析为您选择的结构,然后您可以json_encode。像这样:

$comments = [];
$sx = simplexml_parse_string($xml);
foreach ( $sx->comment as $sx_comment ) {
    $comments[] = [
         // Extract text attributes as appropriate types
         'id' => (int)$sx_comment['id'],
         'user_id' => (int)$sx_comment['user'],
         // Make this one a boolean
         'active' => ( (int)$sx_comment['active'] == 1 ),
         // Maybe you want to format these as ISO 8601...
         'created_ts' => (int)$sx_comment['created'],
         'updated_ts' => (int)$sx_comment['updated'],
         // Extract text content as a string
         'text' => (string)$sx_comment
    ];
}
echo json_encode($comments);