如何使用PHP从含嵌套转义XML的SOAP响应中提取<MenuItemDefinitions>节点数据及相关概念解析
转义内嵌XML的术语及PHP提取方案
首先,回答你的第一个问题:这种嵌套在XML元素内、经过转义的XML内容,通常被称为转义内嵌XML(Escaped Embedded XML),也常被叫做“XML中的XML”——它通过把XML特殊字符(如<转成<、"转成")转义,让外层XML解析器将其视为普通文本,而非嵌套的XML结构。
接下来是PHP的实现方案,结合你现有的SOAP请求代码,我们可以分四步处理:解析外层响应、提取转义文本、反转义、解析内层XML,具体代码和说明如下:
完整处理代码
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://192.168.5.10:8080/EGateway/SimphonyPosApiWeb.asmx"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <GetConfigurationInfo> <vendorCode /> <employeeObjectNum>10009</employeeObjectNum> <configurationInfoType> <int>1</int> </configurationInfoType> <revenueCenter>5</revenueCenter> <configInfoResponse /> </GetConfigurationInfo> </soap:Body> </soap:Envelope>"); curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-Type: text/xml;", "SOAPAction: http://192.168.5.10:8080/EGateway/GetConfigurationInfo" )); $response = curl_exec($ch); curl_close($ch); // 开始处理响应内容 // 1. 解析外层SOAP XML,注意处理命名空间 $soapXml = simplexml_load_string($response, null, LIBXML_NOCDATA); $soapXml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/'); $soapXml->registerXPathNamespace('ns', 'http://micros-hosting.com/EGateway/'); // 2. 定位并提取MenuItemDefinitions节点的文本内容 $menuItemNodes = $soapXml->xpath('//ns:GetConfigurationInfoResponse/ns:configInfoResponse/ns:MenuItemDefinitions'); if (!empty($menuItemNodes)) { $escapedXmlContent = (string)$menuItemNodes[0]; // 3. 反转义XML实体,还原原始XML结构 $rawInnerXml = htmlspecialchars_decode($escapedXmlContent, ENT_QUOTES); // 4. 解析内层XML并处理数据 $innerXml = simplexml_load_string($rawInnerXml); if ($innerXml) { echo "成功解析内层菜单XML数据:\n"; foreach ($innerXml->DbMenuItemDefinition as $menuItem) { echo "菜单ID:" . (string)$menuItem->MenuItemDefID . " | 显示名称:" . (string)$menuItem->Name1->StringText . "\n"; } } else { echo "内层XML解析失败,错误信息:" . libxml_get_last_error()->message; } } else { echo "未在SOAP响应中找到MenuItemDefinitions节点"; } ?>
关键细节说明
- 命名空间处理:SOAP响应包含多个命名空间,必须用
registerXPathNamespace注册对应的命名空间前缀,才能通过XPath精准定位目标节点,避免找不到元素的问题。 - LIBXML_NOCDATA参数:加载外层XML时添加该参数,确保即使节点内容包含CDATA块(你的场景是转义文本,不过加上更通用),也能被正确读取为文本内容。
- 反转义函数:
htmlspecialchars_decode配合ENT_QUOTES参数,可以同时还原<、>、"等XML实体,将转义后的字符串恢复为可解析的原始XML。
内容的提问来源于stack exchange,提问作者Thanuja
相关产品推荐
相关产品推荐

