【问题标题】:PHP - XML Response into ArrayPHP - 对数组的 XML 响应
【发布时间】:2016-07-27 05:00:28
【问题描述】:

我正在使用 PHP 并处理以下 XML 响应:

<CompressedInventoryResults xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/rpc/Gateway">
<CompressedVehicles>
<F _0="vin" _1="stock" _2="msrp" _3="type" _4="year" _5="make" _6="model" _7="imagelist" _8="stockimage"> 
<RS> 
    <R_ID="9002250">
        <VS>
            <V _0="WA1CMAFP3FA096506" _1="A096506" _2="54305" _3="New" _4="2015" _5="Audi" _6="Q5" _7="http://content.homenetiol.com/640x480/53ef04aa3c46463aaa4fd91b13c00037.jpg|http://content.homenetiol.com/640x480/641d6d0da75d457f9026ba35395afdb2.jpg|http://content.homenetiol.com/640x480/4c42f6ff7c7f44eca4613376afef4b22.jpg|http://content.homenetiol.com/640x480/80327447f3bf4421933ca3cae73f9906.jpg|http://content.homenetiol.com/640x480/df7668c77efc4f9692d7809fcb563c98.jpg|http://content.homenetiol.com/640x480/e253195196374c0884c02660fa860b36.jpg|http://content.homenetiol.com/640x480/cae0afb966cf4f1c8430b8807ef761a2.jpg|http://content.homenetiol.com/640x480/b951eee5230c49a583eb0896bb457795.jpg|http://content.homenetiol.com/640x480/a1521a91be614dc19491549fd97fd482.jpg|http://content.homenetiol.com/640x480/563c00e4b19e45f7aba18277541da4c1.jpg|http://content.homenetiol.com/640x480/f47f11edfbf64d5499b842c8b5076376.jpg|http://content.homenetiol.com/640x480/481eb6fcc7b340628b03978e10c2be17.jpg|http://content.homenetiol.com/640x480/dbf461a4a4f349dbbbf9b5bb0b6a0f36.jpg|http://content.homenetiol.com/640x480/3fafb088370f4ee7bec0a3585ef9cec4.jpg|http://content.homenetiol.com/640x480/10908f2cc9da4d418fa752278f635466.jpg|http://content.homenetiol.com/640x480/bf4c4e649b5b4a9db5eb9113ba2d1918.jpg|http://content.homenetiol.com/640x480/7764048b3b5b478a8cf04fb94edad7a8.jpg|http://content.homenetiol.com/640x480/3685da7d1f224386913033e31ee1ebc1.jpg|http://content.homenetiol.com/640x480/f944ff273af044cd91934aabd7651890.jpg|http://content.homenetiol.com/640x480/d8aed10b7d2f471488a1b3f3f6c084d7.jpg|http://content.homenetiol.com/640x480/00d730f575db4db3958a557747358437.jpg|http://content.homenetiol.com/640x480/f104389450e0403f83eb1fb0ffabe3b3.jpg|http://content.homenetiol.com/640x480/df7a41966f0e42859b63738ecaed163e.jpg|http://content.homenetiol.com/640x480/f7d4638bd43d4a119e54decdd0c1d87d.jpg|http://content.homenetiol.com/640x480/29ea28a68bd9426fb85cfc78fb95bdf3.jpg" _8="" />
            <V _0="WAU3GAFD2FN030313" _1="A030313" _2="92095" _3="New" _4="2015" _5="Audi" _6="A8 L" _7="http://content.homenetiol.com/640x480/b358a6a4b58044689c272f098a82e9e9.jpg|http://content.homenetiol.com/640x480/96ac0951ee5043d998d6028ea173ddb8.jpg|http://content.homenetiol.com/640x480/b6a57c34c3bc40acadb09dd6538d6c55.jpg|http://content.homenetiol.com/640x480/17fcb06ee98b41f39a7d9b147652887f.jpg|http://content.homenetiol.com/640x480/3714a45c044a4ddca5a3b7a98b91cd34.jpg|http://content.homenetiol.com/640x480/a5dbc31621574055bbfb7533f4238c14.jpg|http://content.homenetiol.com/640x480/84a9c569786d44b38a65014c20a82160.jpg|http://content.homenetiol.com/640x480/8796e699b9e0451684e0d53d129148b1.jpg|http://content.homenetiol.com/640x480/7c4e8882b392420ca7dfb0f9e9507ede.jpg|http://content.homenetiol.com/640x480/f0d31c64de7549aab70f54fac7bd1056.jpg|http://content.homenetiol.com/640x480/0b4ba4aed8ff41b28c99cb59cc6a6258.jpg|http://content.homenetiol.com/640x480/185f86b4054e4eb08c80eb153527f81a.jpg|http://content.homenetiol.com/640x480/44d65bb194eb4272af48753c8a60622f.jpg|http://content.homenetiol.com/640x480/5d9ac515c8dc4921bc59a1fd1183e95c.jpg|http://content.homenetiol.com/640x480/85c95ff5be6f4bebb79f00e91ac59bf9.jpg|http://content.homenetiol.com/640x480/6be0af9acbc9426d9f4ac9fee1074230.jpg|http://content.homenetiol.com/640x480/cca6e17551f9432fae6859460291d2b2.jpg|http://content.homenetiol.com/640x480/d659f6fccdbb4da0a8bb7f59e493720f.jpg|http://content.homenetiol.com/640x480/7a16f44689d54010b35fa18ce6f1f6cf.jpg|http://content.homenetiol.com/640x480/fdb808588f3045aa9ec85436f5126deb.jpg|http://content.homenetiol.com/640x480/ccf49db7883e47abb14a56a25f050303.jpg|http://content.homenetiol.com/640x480/612d74e48c9e4709ae11645c4dd1ea9b.jpg|http://content.homenetiol.com/640x480/5d398a9e322548cc90bec6ee39307142.jpg|http://content.homenetiol.com/640x480/fc0951a8d8d64e889094f75b8a1f36f2.jpg|http://content.homenetiol.com/640x480/490085ec3cab412ca1aee24c5a169381.jpg|http://content.homenetiol.com/640x480/df9f24289d984879a6cc496c7a9887a6.jpg|http://content.homenetiol.com/640x480/98c616aefd80431687b367dc0805d1e4.jpg" _8="" />
        </VS>
        </R>
</RS>
</F>
</CompressedVehicles>
<ErrorMessage/>
<InventoryResultType>OK</InventoryResultType>
<IsSuccess>true</IsSuccess>
</CompressedInventoryResults>

如何遍历每个 CompressedVehicles 并将每个带有“V”占位符的条目放入一个以“F”条目作为 JSON 输出标头的数组中?

或者有没有更好的方法来与这个响应交互?

最终目标是提供更有用的输出,以供其他与 XML 交互不佳但接受 JSON 的提要中使用。

提前致谢。

【问题讨论】:

  • 首先,最好知道你想要的 JSON 的结构。然后,上面的 XML 不是有效的 XML,这是一个问题。您能否验证它是否与您的回复完全相同?
  • 我猜这在技术上是一个 SOAP XML 响应(根据文档)。
  • 所需的 JSON 输出为:{ vin:"", stock:"", msrp:"", type:"", year:"", make:"", model:"", imagelist:"", stockimage:"" }
  • Soap 生成有效的 XML:您确认它与收到的完全一致吗?请仔细检查:无效的 XML 不可解析:我们可以为您提供一个示例,但它不起作用。 IMO 至少有一对多的下划线。
  • &lt;R_ID="9002250"&gt; 不是 &lt;R _ID="9002250"&gt;&lt;R ID="9002250"&gt; 吗?这是根据您的评论,但与您的问题无关。如果您复制和粘贴,可以是一种简单的方法。

标签: php json xml


【解决方案1】:

要使用 XML 文件,您必须使用 XML 解析器。在这个答案中,您将看到如何使用 SimpleXML Parser。要将数据编码为 JSON 格式,可以使用json_encode 函数。

首先,你要知道你自己的XML文件/字符串的具体结构。在&lt;CompressedInventoryResults&gt; 下你有这个结构:

<CompressedVehicles>
<F>                     <!-- attributes legend -->
<RS> 
    <R>
        <VS>
            <V />       <!-- vehicle -->
            <V />       <!-- vehicle -->
        </VS>
    </R>
</RS>
</F>
</CompressedVehicles>

那么,还有其他系统节点在这个例子中没有用处:&lt;ErrorMessage/&gt;...

基本上,使用 SimpleXML 将 XML 转换为 JSON 格式是一项非常简单的任务:

$xml  = simplexml_load_string( $xmlString );
$json = json_encode( $xml );

通过这种简单的方法,您可以在$json 变量中获得这样的 JSON 字符串:

{
    "CompressedVehicles": {
        "F": {
            "@attributes": { ... },
            "RS": {
                "R": {
                    "@attributes": { "_ID": "9002250" },
                    "VS": {
                        "V": [
                            {
                                "@attributes": { ... }
                            },
                            {
                                "@attributes": { ... }
                            }
                        ]
                    }
                }
            }
        }
    },
    "ErrorMessage": {},
    "InventoryResultType": "OK",
    "IsSuccess": "true"
}

pastebin complete JSON

重新解码:

$data = json_decode( $json );

您可以使用标准 php 语法为对象和数组添加/修改/删除/打印各种元素。

所以,即以下两行:

echo $data->CompressedVehicles->F->{'@attributes'}->_0) . PHP_EOL;
echo $data->CompressedVehicles->F->{'@attributes'}->_1) . PHP_EOL;

将输出:

vin
stock

否则,如果您想访问车辆数据,可以通过foreach 循环来实现:

foreach( $data->CompressedVehicles->F->RS->R->VS->V as $vehicle )
{
    echo $vehicle->{'@attributes'}->_0 . PHP_EOL;
    echo $vehicle->{'@attributes'}->_1 . PHP_EOL;
}

输出:

WA1CMAFP3FA096506
A096506
WAU3GAFD2FN030313
A030313

使用 SimpleXML 创建自定义 JSON

一个(位)更复杂的操作可能是获取您想要的 JSON,尤其是由于 XML 的奇怪结构,它使用编码属性。

加载您的 XML 字符串后:

$xml = simplexml_load_string( $xmlString );

您可以在 XML 结构中导航。 SimpleXML 语法与 php StdObject 语法非常相似:要选择节点级别,您必须使用 -&gt;nodeName;要访问同一级别的单个节点,您可以使用数组语法 (-&gt;nodeName[0]);要访问特定的属性节点,您可以使用数组语法 (-&gt;nodeName[0]['attributeName'])。

因此,选择 &lt;CompressedVehicles&gt; 节点及其所有子节点:

$CompressedVehicles = $xml->CompressedVehicles;

将节点作为 XML 回显:

echo $CompressedVehicles->F->RS->R->VS->V[0]->asXML();
#                                         ↑ only first vehicle

输出:

<V _0="WA1CMAFP3FA096506" _1="A096506" _2="54305" _3="New" ... />

如前所述,您必须为属性创建图例,这些属性列在&lt;F&gt; 节点:

<F _0="vin" _1="stock" _2="msrp" _3="type" _4="year" _5="make" _6="model" _7="imagelist" _8="stockimage"> 

为此,您可以填充一个数组迭代 &lt;F&gt; 节点属性:

$attributes = array();
foreach( $CompressedVehicles->F->attributes() as $key => $val )
{
    $attributes[$key] = $val->__toString();
}

现在,在$attributes 数组中,你有这个:

Array
(
    [_0] => vin
    [_1] => stock
    [_2] => msrp
    [_3] => type
    [_4] => year
    [_5] => make
    [_6] => model
    [_7] => imagelist
    [_8] => stockimage
)

现在是初始化主数组的时候了:

$data = array();

然后您可以对所有&lt;V&gt; 节点执行foreach 循环,并使用来自$attributes 的键填充子数组:

foreach( $CompressedVehicles->F->RS->R->VS->V as $vehicle )
{
    $line = array();
    foreach( $vehicle->attributes() as $key => $val )
    {
        $line[$attributes[$key]] = $val->__toString();
    }

当你在做的时候,为什么不爆炸图像元素呢?

    $line['imagelist'] = explode( '|', $line['imagelist'] );

此时,您可以将子数组添加到主数组:

    $data[] = $line;
}

您可以注意 -&gt;__toString() 语法将 SIMPLEXMLElement 对象转换为字符串。

现在,在您的 $data 中,您有这个:

Array
(
    [0] => Array
        (
            [vin] => WA1CMAFP3FA096506
            [stock] => A096506
            [msrp] => 54305
            [type] => New
            [year] => 2015
            [make] => Audi
            [model] => Q5
            [imagelist] => Array ( ... )
            [stockimage] => 
        )
    [1] => Array ( ... )
)

pastebin complete array structure

您可以将其编码为 JSON 字符串格式:

$json = json_encode( $data );

$json 包含(美化):

[
    {
        "vin": "WA1CMAFP3FA096506",
        "stock": "A096506",
        "msrp": "54305",
        "type": "New",
        "year": "2015",
        "make": "Audi",
        "model": "Q5",
        "imagelist": [
            "http:\/\/content.homenetiol.com\/640x480\/53ef04aa3c46463aaa4fd91b13c00037.jpg",
            ...
        ],
        "stockimage": ""
    },
    {
        "vin": "WAU3GAFD2FN030313",
        ...
    }
]

pastebin complete JSON

【讨论】:

  • 这太棒了——感谢您花时间详细解释一切——就像冠军一样。
  • 如果出现以下情况怎么办:&lt;CompressedVehicles&gt; &lt;F&gt; &lt;!-- attributes legend --&gt; &lt;RS&gt; &lt;R&gt; &lt;VS&gt; &lt;V /&gt; &lt;!-- vehicle --&gt; &lt;V /&gt; &lt;!-- vehicle --&gt; &lt;/VS&gt; &lt;/R&gt; &lt;R&gt; &lt;VS&gt; &lt;V /&gt; &lt;!-- vehicle --&gt; &lt;V /&gt; &lt;!-- vehicle --&gt; &lt;/VS&gt; &lt;/R&gt; &lt;/RS&gt; &lt;/F&gt; &lt;/CompressedVehicles&gt; 存在多个&lt;R&gt; 条目?
  • 只需遍历&lt;R&gt;。请注意,这必须是一个新问题。 ...但我相信只要稍加努力,您就可以自己找到路!机制不会改变,您只需迭代不同的级别。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
相关资源
最近更新 更多