PHP 使用 SimpleXML 对象从 XML 转换为 JSON。带有 <items> 标签的数组导致问题
PHP Converting from XML to JSON with a SimpleXML object. Array with <items> tag causing issues
我们正在使用 SimpleXML 尝试将 XML 转换为 JSON,然后再转换为 PHP 对象,以便我们可以比较 Soap API 与我们的休息 API。我们有一个请求 returns 相当多的数据,但有问题的部分是我们有嵌套数组的地方。
返回的数组带有 XML 中的标记,但我们不希望将其转换为 JSON。
得到的XML如下:
<apns>
<item>
<apn>apn</apn>
</item>
</apns>
所以当它被翻译成JSON时,它看起来像这样:
{"apns":{"item":{"apn":"apn"}}
实际上,我们希望 SimpleXML 转换为与我们的 Rest API 相同的 JSON,如下所示:
{"apns":[{"apn":"apn"}]}
数组可以包含不止一个东西,例如:
<apns>
<item>
<apn>apn</apn>
</item>
<item>
<apn>apn2</apn>
</item>
</apns>
我假设这只会在 JSON 中出错或覆盖第一个。
我希望 SimpleXML 能够在本机处理这个问题,但如果没有,是否有人得到了不涉及 janky 字符串操作的修复程序?
TIA :)
我希望这段代码可以用作您之后的模板,问题是很难知道这是否是您尝试做的唯一实例...
它所做的是首先使用 XPath 查找在下面具有 item/apn
结构的任何节点(//*[item/apn]
表示任何节点 //*
下面有以下节点)。
然后循环遍历这些项目并在每个 <item>
的起始节点(本例中为 <apns>
节点)下添加新的 <apn>
节点,其值为 ($list->addChild("apn", (string)$item->apn);
.
复制节点后,它会删除所有 <item>
个节点 (unset($list->item);
)。
$input = '<apns>
<item>
<apn>apn</apn>
</item>
<item>
<apn>apn2</apn>
</item>
</apns>';
$xml = simplexml_load_string($input);
$itemList = $xml->xpath("//*[item/apn]");
foreach ( $itemList as $list ) {
foreach ( $list->item as $item ) {
$list->addChild("apn", (string)$item->apn);
}
unset($list->item);
}
echo $xml->asXML();
给...
<?xml version="1.0"?>
<apns>
<apn>apn</apn><apn>apn2</apn></apns>
和
echo json_encode($xml);
给...
{"apn":["apn","apn2"]}
如果你只想要最后一个值,那么你可以只跟踪最后一个值并在内循环之外设置新元素...
$itemList = $xml->xpath("//*[item/apn]");
foreach ( $itemList as $list ) {
foreach ( $list->item as $item ) {
$apn = (string)$item->apn;
}
$list->addChild("apn", $apn);
unset($list->item);
}
泛型转换不可能知道单个元素应该是 JSON 中的数组。
SimpleXMLElement
属性可以作为一个 Iterable 来遍历同名兄弟。它们可以被视为一个列表或单个值。
这允许您构建自己的 array/object 结构并将其序列化为 JSON。
$xml = <<<'XML'
<apns>
<item>
<apn>apn1</apn>
</item>
<item>
<apn>apn2</apn>
</item>
</apns>
XML;
$apns = new SimpleXMLElement($xml);
$json = [
'apns' => []
];
foreach ($apns->item as $item) {
$json['apns'][] = ['apn' => (string)$item->apn];
}
echo json_encode($json, JSON_PRETTY_PRINT);
这仍然允许您以一般方式 read/convert 零件。更深入地了解 SimpleXMLElement class。这是迭代所有子节点或获取当前节点名称的方法。
我们正在使用 SimpleXML 尝试将 XML 转换为 JSON,然后再转换为 PHP 对象,以便我们可以比较 Soap API 与我们的休息 API。我们有一个请求 returns 相当多的数据,但有问题的部分是我们有嵌套数组的地方。
返回的数组带有 XML 中的标记,但我们不希望将其转换为 JSON。
得到的XML如下:
<apns>
<item>
<apn>apn</apn>
</item>
</apns>
所以当它被翻译成JSON时,它看起来像这样:
{"apns":{"item":{"apn":"apn"}}
实际上,我们希望 SimpleXML 转换为与我们的 Rest API 相同的 JSON,如下所示:
{"apns":[{"apn":"apn"}]}
数组可以包含不止一个东西,例如:
<apns>
<item>
<apn>apn</apn>
</item>
<item>
<apn>apn2</apn>
</item>
</apns>
我假设这只会在 JSON 中出错或覆盖第一个。
我希望 SimpleXML 能够在本机处理这个问题,但如果没有,是否有人得到了不涉及 janky 字符串操作的修复程序?
TIA :)
我希望这段代码可以用作您之后的模板,问题是很难知道这是否是您尝试做的唯一实例...
它所做的是首先使用 XPath 查找在下面具有 item/apn
结构的任何节点(//*[item/apn]
表示任何节点 //*
下面有以下节点)。
然后循环遍历这些项目并在每个 <item>
的起始节点(本例中为 <apns>
节点)下添加新的 <apn>
节点,其值为 ($list->addChild("apn", (string)$item->apn);
.
复制节点后,它会删除所有 <item>
个节点 (unset($list->item);
)。
$input = '<apns>
<item>
<apn>apn</apn>
</item>
<item>
<apn>apn2</apn>
</item>
</apns>';
$xml = simplexml_load_string($input);
$itemList = $xml->xpath("//*[item/apn]");
foreach ( $itemList as $list ) {
foreach ( $list->item as $item ) {
$list->addChild("apn", (string)$item->apn);
}
unset($list->item);
}
echo $xml->asXML();
给...
<?xml version="1.0"?>
<apns>
<apn>apn</apn><apn>apn2</apn></apns>
和
echo json_encode($xml);
给...
{"apn":["apn","apn2"]}
如果你只想要最后一个值,那么你可以只跟踪最后一个值并在内循环之外设置新元素...
$itemList = $xml->xpath("//*[item/apn]");
foreach ( $itemList as $list ) {
foreach ( $list->item as $item ) {
$apn = (string)$item->apn;
}
$list->addChild("apn", $apn);
unset($list->item);
}
泛型转换不可能知道单个元素应该是 JSON 中的数组。
SimpleXMLElement
属性可以作为一个 Iterable 来遍历同名兄弟。它们可以被视为一个列表或单个值。
这允许您构建自己的 array/object 结构并将其序列化为 JSON。
$xml = <<<'XML'
<apns>
<item>
<apn>apn1</apn>
</item>
<item>
<apn>apn2</apn>
</item>
</apns>
XML;
$apns = new SimpleXMLElement($xml);
$json = [
'apns' => []
];
foreach ($apns->item as $item) {
$json['apns'][] = ['apn' => (string)$item->apn];
}
echo json_encode($json, JSON_PRETTY_PRINT);
这仍然允许您以一般方式 read/convert 零件。更深入地了解 SimpleXMLElement class。这是迭代所有子节点或获取当前节点名称的方法。