当XML SOAP响应中只有一个元素时,使用JSON对象而不是数组

3

我正在调用一个返回XML数据的Web服务。当我将xml数据转换为json时,问题就出现了。某些应该返回对象数组的元素,在只有一个值时,不会被转换为仅包含一个对象的数组,而是变成了一个对象。因此,与其拥有:

{
"products":[ { "title":"Title 1",  "attributes":[{"color":"blue"}] } ]
}

我理解

{
"products":{ "title":"Title 1", "attributes":{"color":"blue"} }
}

PHP数组现在是这样的:

[products] => Array ( [title] => 标题1 [attributes] => Array ( [color] => 蓝色 ) )

而不是这样:

[products] => Array ( [0] => Array ( [title] => 标题1 [attributes] => Array ([0] => Array ([color] => 蓝色 ) ) )

所以我已经做了以下工作:

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

 if (isset($array['products']) && !isset($array['products'][0])) {
       $array['products'] = array($array['products']);
 } 

我检查是否存在名为“products”的数组,如果没有索引0,我将其嵌套在一个新的数组中。这样做就可以解决问题。然后我对属性数组也做同样的操作,如下所示:

    $products = $array['products'];

    $array['products'] = [];

    foreach ($products as $product) {

        if (isset($product['attributes']) && !isset($product['attributes'][0])) {

            $product['attributes'] = array($product['attributes']);

        }

        array_push($array['products'], product);
    }

在这里,我将产品数组绑定到一个名为products的变量中以在循环中使用它,然后清空该数组。在创建新属性数组后,我将更改后的产品填入产品数组中。

我的问题是:

有没有更好的方法来处理这件事?我不喜欢我在这里做的事情,但我想不出其他办法......

编辑

这是我的soap请求:


    $client = new SoapClient($wsdl, $soapOptions);

    $soapHeader = WsSecurity::createWsSecuritySoapHeader($username, $password, false, $synced, 60, true, true, false, true);

    $client->__setSoapHeaders($soapHeader);

    $response = $client->dateRetrieveMovement($dateMovementRequest);

    $movements = $response->DateMovementRequestResult->movements;
    $movementInfo = $movements->movementInfo;
    $messages = $movementInfo->messages->messageExchanged;

    $messageData = $messages->IEMessage->xmlData;

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

1
你能展示一些演示问题的XML样本吗? - Nick
我在任何时候都不处理实际的XML,也不控制Web服务。我使用SOAP客户端,发出请求,然后将响应传递给simplexml_load_string()函数... - gothaf
我在这里所做的达到了目的,但我想知道是否有更简洁的方法可以实现... - gothaf
如果我们有一个非常小的XML示例,我相信我们将能够更好地帮助您。 - Ebrahim Mohammed
所以,消息数据的 var_dump :) - Ebrahim Mohammed
各位,如果你们熟悉SOAP客户端,应该知道它不会返回实际的XML,而是返回一个对象...如果你想要,我可以给你展示XSDs,但我不知道这样做会有什么帮助... - gothaf
1个回答

0
问题是“是否有更好的方法来进行XML到JSON转换”,我认为答案是“没有,除非进行一些编码”。
标准的XML-to-JSON转换库简单地不知道足够关于您的数据模型的语义以产生一个体面的数据表示。理论上,工具可以尝试从模式或其他地方提取这样的信息,但我不知道有任何这样的工具。
编写自定义XSLT转换以产生您想要的JSON并不太困难,特别是使用XSLT 3.0,这可能比在接收应用程序中修补JSON的方式更容易。

这似乎是正确方向的答案。这是我第一次需要处理XML,目前为止这是一个非常令人沮丧的经历。从我的理解来看,如果soap客户端使用wsdl文件进行编码/解码发送和接收的数据,我是否需要在两者之间“注入”一个xslt文件以进行适当的更改,或者还有不同的方法来进行请求? - gothaf
将您的应用程序构建为转换阶段的管道通常是一个好的实践,也得到了许多应用程序框架的支持,因此注入XSLT转换步骤应该会感觉很自然和正常。 - Michael Kay
Kay先生,我读了一些关于XSLT的东西,看了一些教程,甚至偶然发现了您使用XSLT 3.0转换JSON的演示文稿。不幸的是,现在我对这个概念没有很牢固的理解,我认为我不能像我想象的那样轻松地完成这个任务。如果您能够友善地指引我完成任务所需的任何相关资源、应该使用的任何工具或应该采取的步骤,我将不胜感激。无论如何,我都要感谢您花时间指引我走向正确的道路。 - gothaf
@gotahf,有许多书籍、教程、培训课程,取决于你自己的学习风格才能确定哪种适合你。有些人只阅读W3C规范:它并不像你想象的那样令人畏惧,并且包含了很多好的例子!但是像任何新语言一样,都需要一个学习曲线,你必须努力学习才能熟练掌握。 - Michael Kay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接