simplexml_load_string()不会读取标签中带有“soap:”的soap响应[重复]

Posted

技术标签:

【中文标题】simplexml_load_string()不会读取标签中带有“soap:”的soap响应[重复]【英文标题】:simplexml_load_string() will not read soap response with "soap:" in the tags [duplicate] 【发布时间】:2012-09-11 04:45:34 【问题描述】:

我知道这可能是一个新手问题,但请幽默。读取标签中带有“soap:”的 xml 字符串时,simplexml_load_string() 不会读取 xml。

给定这个脚本:

#!/usr/bin/php
<?php

$s='
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
        <soap:Header>
        <context xmlns="urn:zimbra"/>
        </soap:Header>
        <soap:Body>
            <AuthResponse xmlns="urn:zimbraAdmin">
                <authToken>somevalue</authToken>
                <lifetime>123124123</lifetime>
                <a n="zimbraIsDomainAdminAccount">false</a>
            </AuthResponse>
        </soap:Body>
    </soap:Envelope>';


print_r(simplexml_load_string($s));
echo "\n\n";
print_r(simplexml_load_string(str_ireplace("soap:", "", $s)));
?>

我得到这个输出:

jesse@jesse-debian:~/code/zmsoap$ ./xmltest.php 
SimpleXMLElement Object
(
)

SimpleXMLElement Object
(
    [Header] => SimpleXMLElement Object
        (
            [context] => SimpleXMLElement Object
                (
                )

        )

    [Body] => SimpleXMLElement Object
        (
            [AuthResponse] => SimpleXMLElement Object
                (
                    [authToken] => somevalue
                    [lifetime] => 123124123
                    [a] => false
                )

        )

)
jesse@jesse-debian:~/code/zmsoap$

我只是好奇为什么会发生这种情况,以及是否有比进行字符串替换更合适的方法来解决问题。

【问题讨论】:

看起来是命名空间的问题。 【参考方案1】:

带有冒号的标签名称表示该标签位于非默认命名空间中。 SimpleXML 一次只查看一个命名空间,因此您需要使用the -&gt;children() method 专门选择命名空间。

在这种情况下,$xml-&gt;children('http://www.w3.org/2003/05/soap-envelope')-&gt;Body$xml-&gt;children('soap', true)-&gt;Body 应该都可以工作。

出于这个和其他原因,不建议使用print_r 来调试 SimpleXML 对象。请改用this dedicated function。

【讨论】:

感谢您的解决方案...经过长时间的搜索得到了这个...【参考方案2】:

这似乎奏效了。

在这里阅读:Parse XML with Namespace using SimpleXML

#!/usr/bin/php
<?php

$s='
    <soap:Envelope xmlns:soap="urn:zimbra">
        <soap:Header>
        <context xmlns="urn:zimbra"/>
        </soap:Header>
        <soap:Body>
            <AuthResponse xmlns="urn:zimbraAdmin">
                <authToken>somevalue</authToken>
                <lifetime>123124123</lifetime>
                <a n="zimbraIsDomainAdminAccount">false</a>
            </AuthResponse>
        </soap:Body>
    </soap:Envelope>';
//print_r(simplexml_load_string($s));
//echo "\n\n";
//print_r(simplexml_load_string(str_ireplace("soap:", "", $s)));
$xml = simplexml_load_string($s);
$xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
print_r($xml->xpath('//soap:Body'));

?>

【讨论】:

您可以在不触及 XPath 的情况下执行此操作,而只需使用主要的 SimpleXML 函数/运算符。请参阅我刚刚添加的答案。【参考方案3】:

最简单的:

$xml='<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><AddOrderResult>1</AddOrderResult></soap:Body></soap:Envelope>';
var_export(json_decode(json_encode(simplexml_load_string(strtr($xml, array(' xmlns:'=>' ')))), 1));

输出:

array (
  '@attributes' => 
  array (
    'soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
  ),
  'soap:Body' => 
  array (
    'AddOrderResult' => '1',
  ),
)

【讨论】:

我不明白这怎么可能最简单json_decode(json_encode 也没有任何意义。

以上是关于simplexml_load_string()不会读取标签中带有“soap:”的soap响应[重复]的主要内容,如果未能解决你的问题,请参考以下文章

PHP:SimpleXMLElement() 类和 SimpleXML_load_string() 有啥区别?

simplexml_load_string 抛出“未注册的错误消息”

simplexml_load_string 转换xml为数组

使用属性包含斜杠的 simplexml_load_string 将 XML 转换为数组

使用 simplexml_load_string 获取 xml 属性 [重复]

simplexml_load_string 函数中的错误