json_encode() 删除属性 (PHP)
Posted
技术标签:
【中文标题】json_encode() 删除属性 (PHP)【英文标题】:json_encode() removes attributes (PHP) 【发布时间】:2017-01-21 06:16:41 【问题描述】:我在 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 的所有属性发生了什么?
谢谢,感谢您的帮助!
编辑:我发现只要给定节点只有一个文本值:<something attribute="will be dropped">just text</something>
,就会删除 XML 元素的所有属性。
所以目前我正在使用一个丑陋的解决方法:我已经修改了代码,在将 XML 提供给simplexml_load_string()
之前,它用<text>string</text>
替换了所有出现的字符串。这个解决方案目前运行良好,但我仍然对更清洁的解决方案感兴趣......
【问题讨论】:
那不是json数据使用simplexml_load_string()
!在json
他们不是attributes
或nodes
,只是array
或objects with fields
....
@JustOnUnderMillions:我已经在使用 simplexml_load_string()。 (抱歉,忘了提这个问题。我已经更新了问题。)
是的,已经注意到了。你在这里遇到了一件棘手的事情:)
@PaulCrovella SimpleXML 不是一个糟糕的 API,但它是一个糟糕的选择 API,用于盲目地将 XML 转换为 JSON,坦率地说,这是一件很奇怪的事情.这是一个很棒的 API,用于实际处理 XML 数据,例如在控制流或模板中使用值。
@Paul Crovella 你的意思是 above:命名空间和其他东西吗?我注意到的一件事是,当我解析一个 1GB 的 xml 时,它使用了 10GB 内存 :) 我使用了 PARSE_HUGH 标志。但是 SimpleXML 像 PHP 中的所有东西一样既棘手又有趣
【参考方案1】:
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);
【讨论】:
【参考方案2】:您的 json 输出显示最后一条评论的最后一个 id。所以json_encode()
覆盖了每次迭代的“评论”。您必须准备好您的xml
数据,然后才能将其提供给json_decode()
。因此,将 XML 解析为对象 simplexml
,然后从中创建一个 php 数组,这样您就可以 encode
该数组。我不认为你在这里得到 one-liner-solution ;)
对于您的问题: 谁能解释一下 cmets 的所有属性发生了什么?
没有缺少attributes
,1-5 中的<comment>
s 不会出现在 json 中。
更新:对不起,没有看到这部分"Something","Hello","Just a comment",
,这真的很有线。所有 cmets 都在那里,但在同一个数组中是属性!?!?而属性本身就是一个对象!?
你必须像我上面说的那样自己准备。没办法。您不能依赖 json_encode(simpelxml_load_string('XML')) 的结果,SimpleXML 不是为此而生的!
【讨论】:
以上是关于json_encode() 删除属性 (PHP)的主要内容,如果未能解决你的问题,请参考以下文章
使用 JSON 将 XML 转换为 PHP 数组正在删除某些元素的属性