You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中如何解析带多命名空间的SOAP请求并转为数组或JSON

SOAP报文转数组/JSON解决方案

直接调用simplexml_load_string后转JSON返回空,是因为SOAP报文携带多个命名空间,SimpleXML默认不会自动导出命名空间下的节点内容。使用支持命名空间的自定义转换函数即可解决,具体实现如下:

完整实现代码

/**
 * 支持命名空间的XML转数组函数
 * @param SimpleXMLElement $xml 加载后的XML对象
 * @return array|string
 */
function xmlToArray(SimpleXMLElement $xml)
{
    $result = [];

    // 提取当前节点属性
    if ($attrs = $xml->attributes()) {
        foreach ($attrs as $key => $val) {
            $result['@attributes'][$key] = (string)$val;
        }
    }

    // 遍历所有命名空间的子节点
    $namespaces = $xml->getDocNamespaces(true);
    foreach ($namespaces as $nsPrefix => $nsUri) {
        foreach ($xml->children($nsUri) as $childKey => $childNode) {
            // 节点名默认携带命名空间前缀避免冲突,不需要可去掉前缀直接用$childKey
            $nodeKey = $nsPrefix ? "{$nsPrefix}:{$childKey}" : $childKey;
            $childArr = xmlToArray($childNode);

            // 处理同标签名多节点的数组兼容
            if (isset($result[$nodeKey])) {
                if (!is_array($result[$nodeKey]) || !isset($result[$nodeKey][0])) {
                    $result[$nodeKey] = [$result[$nodeKey]];
                }
                $result[$nodeKey][] = $childArr;
            } else {
                $result[$nodeKey] = $childArr;
            }
        }
    }

    // 提取节点文本内容
    $text = trim((string)$xml);
    if (empty($result)) {
        return $text;
    }
    if ($text !== '') {
        $result['@value'] = $text;
    }

    return $result;
}

// 调用示例
// 你的SOAP报文字符串
$soapXml = <<<XML
<soap-env:Envelope
    xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header
        xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        <wsse:Security
            xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustunderstand="1">
            <wsse:UsernameToken>
                <wsse:Username>username</wsse:Username>
                <wsse:Password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#passwordtext">secret</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </soap-env:Header>
    <soap-env:Body
        xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        <OTA_HotelResNotifRQ
            xmlns="http://www.opentravel.org/OTA/2003/05" Version="1.0" EchoToken="4528545b-f875-5c77-9205-22631b68f15a" ResStatus="Commit" TimeStamp="2018-07-31T01:16:16Z">
            ...
        </OTA_HotelResNotifRQ>
    </soap-env:Body>
</soap-env:Envelope>
XML;

// 加载XML,含CDATA请加LIBXML_NOCDATA参数
$xmlObj = simplexml_load_string($soapXml);
$soapArray = xmlToArray($xmlObj);
// 转JSON输出
$soapJson = json_encode($soapArray, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

访问示例

转换后可直接通过键名访问所有内容:

  • 获取用户名:$soapArray['soap-env:Header']['wsse:Security']['wsse:UsernameToken']['wsse:Username']
  • 获取业务节点版本号:$soapArray['soap-env:Body']['OTA_HotelResNotifRQ']['@attributes']['Version']

内容的提问来源于stack exchange,提问作者Edi 0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:18:02