【问题标题】:SoapClient XML return string with simpleXML带有 simpleXML 的 SoapClient XML 返回字符串
【发布时间】:2023-03-08 05:51:01
【问题描述】:

所以我从肥皂服务(我无法控制)中获取了一个 xml 文件。它返回一个导致 simpleXML 问题的 xmlns。我正在运行 str_replace 来解决这个问题,但是现在 simpleXML 只返回一个空对象。 XML 结构似乎很好,没有错误只是一个空对象。

$xmlString = $client->__getLastResponse();
$feed = str_replace(' xmlns="LMSWebservice"', '', $xmlString);
$sData= simplexml_load_string($feed);

print_r($sData);

返回:SimpleXMLElement Object()

str替换前的XML源是:

<?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <GetUserInternalIDByPersonalIDResponse xmlns="LMSWebservice">
                <GetUserInternalIDByPersonalIDResult>
                    <Response xmlns="">
                        <Timestamp date="24/10/2013" time="04:27:37" />
                        <User>
                           <UserInternalID>4907</UserInternalID>
                        </User>
                    </Response>
                </GetUserInternalIDByPersonalIDResult>
           </GetUserInternalIDByPersonalIDResponse>
       </soap:Body>
  </soap:Envelope>

str替换后:

<?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <GetUserInternalIDByPersonalIDResponse>
                <GetUserInternalIDByPersonalIDResult>
                    <Response xmlns="">
                        <Timestamp date="24/10/2013" time="04:27:37" />
                        <User>
                           <UserInternalID>4907</UserInternalID>
                        </User>
                    </Response>
                </GetUserInternalIDByPersonalIDResult>
           </GetUserInternalIDByPersonalIDResponse>
       </soap:Body>
  </soap:Envelope>

任何帮助将不胜感激,这让我发疯!

----因此,如果我不摆脱命名空间属性,我会收到以下错误消息:


警告:simplexml_load_string() [function.simplexml-load-string]:实体:第 1 行:解析器警告:xmlns:URI LMSWebservice 在 serviceTest2.php 中不是绝对的16 行

警告: simplexml_load_string() [function.simplexml-load-string]: LSchema"> serviceTest2.php 中的 16

警告:simplexml_load_string() [function.simplexml -load-string]: ^ in serviceTest2.php16

如果我尝试使用 xPath 获取 UserInternalID,它会返回一个空数组。如果您所说的是正确的并且这将正确地进入 simpleXML,那么我如何访问 UserInternalID 节点?抱歉,这是第一次使用 simpleXML,这让我很困惑。

所以只是尝试更改 NS

$feed = str_replace('xmlns="LMSWebservice"', 'xmlns="ns:LMSWebservice"', $xmlString);

进入没有错误。

我在 xPath 上试过这个 $ID = $sData->xpath('UserInternalID');

我知道这可能是完全错误的,但我没有尝试太多其他方法,因为它似乎一开始就没有正确地进入 simpleXML。 :/

所以我用过 $ID = $sData->xpath('//UserInternalID'); 回声 $ID[0];

效果很好。感谢您的所有帮助!

【问题讨论】:

  • 您不能说该对象是否为空,因为 PHP 的 SimpleXMLElement 确实会即时添加属性(它是通过魔术完成的),因此将 var_dump 或 print_r 与 SimpleXMLElement 一起使用没有多大意义.请参阅:SimpleXML and print_r() - why is this empty? - 它还涵盖了您认为 simplexml 无法处理的与 XML 命名空间相关的问题(这样说是错误的)。
  • 添加了与您的评论相关的更多信息
  • 好吧,你说得对,警告是正确的,xmlns 需要一个 URI,xmlns="LMSWebservice" 没有这样的 URI。这实际上意味着您正在与之通信的服务不是 SOAP 服务,如果您想这样使用它,您必须将问题告诉服务供应商。其他所有内容都未指定,您可能应该使用代理。为了更好地从无效的 XML 中恢复,您可以将 ' xmlns="LMSWebservice"' 替换为 ' xmlns="ns:LMSWebservice"'。那 (ns:LMSWebservice) 是一个有效的 URI。这可能已经对您有所帮助。
  • 你应该举一个例子来说明你如何进行 xpath 查询。您只是说您的尝试不起作用,但是不清楚您到底尝试了什么(如果很明显它不起作用并且是尝试的示例,则可以发布不起作用的代码)。
  • 好的,刚试了你说的,看到上面的回复。

标签: php xml simplexml


【解决方案1】:
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($response);
libxml_clear_errors();
$xml = $doc->saveXML($doc->documentElement);
$xml = simplexml_load_string($xml);

使用它对我有很大帮助。

【讨论】:

    【解决方案2】:

    通过广泛的 cmets 和您的最后一次编辑,最终可以揭示问题的实际原因,xpath 表达式是错误的:

    $ID = $sData->xpath('UserInternalID');
    

    路径错误,它不匹配任何元素。相反,您可以使用:

    $ID = (string) $xml->xpath('//UserInternalID')[0];
    

    或更详细:

    $ID = (string) $xml->xpath('//Response/User/UserInternalID')[0];
    

    这里的关键是您要为要查询的元素编写正确的路径。

    完整使用示例:

    <?php
    /**
     * SoapClient xml return string with simpleXML
     *
     * @link http://stackoverflow.com/q/19556414/367456
     */
    
    $response = <<<RESPONSE
    <?xml version="1.0" encoding="utf-8"?>
        <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <soap:Body>
                <GetUserInternalIDByPersonalIDResponse xmlns="LMSWebservice">
                    <GetUserInternalIDByPersonalIDResult>
                        <Response xmlns="">
                            <Timestamp date="24/10/2013" time="04:27:37" />
                            <User>
                               <UserInternalID>4907</UserInternalID>
                            </User>
                        </Response>
                    </GetUserInternalIDByPersonalIDResult>
               </GetUserInternalIDByPersonalIDResponse>
           </soap:Body>
      </soap:Envelope>
    RESPONSE;
    
    $restore = libxml_use_internal_errors(TRUE);
    $xml     = simplexml_load_string($response);
    libxml_use_internal_errors($restore);
    
    echo $xml->xpath('//Response/User/UserInternalID')[0];
    

    输出:

    4907
    

    在线演示:https://eval.in/57149

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2011-06-30
      • 1970-01-01
      • 2015-07-05
      • 2011-06-10
      • 1970-01-01
      相关资源
      最近更新 更多