当 XML SOAP 响应中存在单个元素时,JSON 对象而不是数组
Posted
技术标签:
【中文标题】当 XML SOAP 响应中存在单个元素时,JSON 对象而不是数组【英文标题】:JSON object instead of array when a single element is present on XML SOAP response 【发布时间】:2020-05-31 21:01:40 【问题描述】:我正在使用一个返回一些 XML 数据的 Web 服务。当我将 xml 数据转换为 json 时,问题就开始了。一些应该返回对象数组的元素,当它们只有一个值时,它们不会转换为内部有单个对象的数组,它们会变成一个对象。所以不要有:
"products":[ "title":"Title 1", "attributes":["color":"blue"] ]
我明白了
"products": "title":"Title 1", "attributes":"color":"blue"
php 数组看起来像这样
[products] => Array ( [title] => Title 1 [attributes] => Array ( [color] => blue ) )
而不是这个
[products] => Array ( [0] => Array ( [title] => Title 1
[attributes] => Array ([0] => Array ([color] => blue ) ) )
所以我所做的如下:
$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 数组绑定到一个名为 products
的变量以在循环中使用它,然后我清空数组并在创建新的 attributes 数组后,用更改的产品填充 products 数组。
我的问题是:
有没有更好的方法来处理这件事?我不喜欢我在这里做的事情,但我想不出别的……
编辑
这是我的肥皂请求:
$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);
【问题讨论】:
您能否展示一些示例 XML 来演示该问题? 我在任何时候都不处理实际的 XML,也不控制 Web 服务。我使用一个肥皂客户端,我发出请求,然后我通过simplexml_load_string()
函数的响应...
我在这里所做的事情是为了达到目的,但我想知道它是否可以以更时尚的方式完成......
如果我们有一个非常小的 xml 样本,我相信我们将能够更好地帮助您
所以 var 转储 messageData :)
【参考方案1】:
问题是“有没有更好的方法来进行 XML 到 JSON 的转换”,我认为答案是“不是不做一些编码”。
标准的 XML 到 JSON 转换库对数据模型的语义了解不足,无法生成合适的数据表示形式。从理论上讲,一个工具可以尝试从模式或其他地方提取此类信息,但我不知道有什么这样做的。
编写自定义 XSLT 转换以准确生成您想要的 JSON 并不太困难,尤其是使用 XSLT 3.0,而且这可能比按照您描述的方式在接收应用程序中修补 JSON 更省力。
【讨论】:
这似乎是对正确方向的回答。这是我第一次需要处理 XML,到目前为止,这是一次非常令人沮丧的经历。据我了解,如果soap客户端使用wsdl文件对发送和接收的数据进行编码/解码,我是否必须在两者之间“注入”一个xslt文件以进行适当的更改,或者是否有不同的方法来发出请求? 将您的应用程序构建为转换阶段的管道通常是一种很好的做法,并且受到许多应用程序框架的支持,因此注入 XSLT 转换步骤应该感觉正常和自然。 先生。凯,我读了一些关于 XSLT 的东西,我看了一些教程,我什至偶然发现了你关于使用 XSLT 3.0 转换 JSON 的演示文稿。不幸的是,现在我对这个概念没有深入的了解,而且我认为我不能像我想象的那样容易地解决这个问题。如果您愿意向我指出与我需要完成的任务或我应该使用的任何工具或我应该采取的步骤相关的任何资源,我将不胜感激。无论如何,我要感谢您花时间引导我走上正确的道路。 @gothaf 有很多书籍、教程、培训课程,适合你的取决于你自己的学习方式。有些人只是阅读了 W3C 规范:它并不像您想象的那么令人生畏,并且有很多很好的例子!但与任何新语言一样,都有一个学习曲线,您必须努力学习才能精通。以上是关于当 XML SOAP 响应中存在单个元素时,JSON 对象而不是数组的主要内容,如果未能解决你的问题,请参考以下文章
使用Savon和Nokogiri在Rails中解析XML SOAP响应的内存不足
当内容类型为“text/xml”时,Axis2 发送多部分响应