XML 不能用 soap-env 解析,在 PHP 中有自定义标签

问题描述 投票:0回答:2
php xml soap xml-parsing
2个回答
0
投票

好吧,在花了几个小时之后,我终于明白了! 我不得不根据如下标签名称进行修改,在大多数情况下,我不得不使用 soap-env 而不是 SOAP.


            $dom = new DOMDocument;
            $dom->preserveWhiteSpace = false;
            $dom->loadXML($response->Data);
            $dom->formatOutput = true;      
            $XMLContent = $dom->saveXML();

            $xml = simplexml_load_String($XMLContent, null, null, 'soap-env', true);    

            if(!$xml)
                trigger_error("Encoding Error!", E_USER_ERROR);
            
            $Results = $xml->children('soap-env',true);
                
            foreach($Results->children('soap-env',true) as $fault){
                if(strcmp($fault->getName(),'Fault') == 0){
                    trigger_error("Error occurred request/response processing!", E_USER_ERROR);
                }
            }
    
            foreach($Results->children('wsse',true) as $nodes){         
                if(strcmp($nodes->getName(),'Security') == 0){
                    foreach($nodes->children('wsse',true) as $securityNodes){
                        if(strcmp($securityNodes->getName(),'BinarySecurityToken') == 0){                           
                            $tokenParsed = (string)$securityNodes;                                                      
                        }
                    }
                }           
            }

0
投票

这就是SOAP,一种使用XML语法的对象序列化格式。最佳解决方案是使用 SOAP 库。 PHP 对此有

ext/soap
。使用 XML 库会低一个级别。

XML 使用命名空间。名称空间是使用唯一的 URI 指定的。为了可读性/可维护性,XML 为 URI 定义了别名,并将它们用作节点名称的前缀。但是以下3个例子都应该读作

{http://schemas.xmlsoap.org/soap/envelope/}envelope

  • <soap-env:envelope xmlns::soap-env="http://schemas.xmlsoap.org/soap/envelope/"/>
  • <soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>
  • <envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"/>

命名空间可以在任何元素节点上定义,因此它们甚至可以在单个文档中更改。这意味着您的代码不应该依赖于文档中的别名/前缀,而是名称空间 URI。

我强烈建议为使用的命名空间定义一个数组变量/常量。然后你可以使用 Xpath 和命名空间感知 DOM 方法(后缀

NS
)。

// used namespaces, the keys do NOT need to match the prefixes in the XML.
$xmlns = [
    'soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
    'eb' => 'http://www.ebxml.org/namespaces/messageHeader',
    'sec' => 'http://schemas.xmlsoap.org/ws/2002/12/secext'
];

$document = new DOMDocument();
$document->loadXML(getSoapXmlString());
$xpath = new DOMXpath($document);
// register your aliases for the namespaces
foreach ($xmlns as $alias => $uri) {
    $xpath->registerNamespace($alias, $uri);
}

$token = $xpath->evaluate(
  'string(//sec:security/sec:binarysecuritytoken)'
); 

var_dump($token);

DOMXpath::evaluate()
允许 Xpath 表达式返回节点列表和标量值。如果将节点列表(由位置路径指定)转换为字符串,它将返回第一个节点的文本内容或空字符串。

© www.soinside.com 2019 - 2024. All rights reserved.