在PHP中解析XML响应时遇到错误
当我从CURL请求调用时,我收到一个低于XML的响应
<?xml version="1.0" encoding="UTF-8"?> <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header>
<eb:MessageHeader xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" eb:version="1.0" soap-env:mustUnderstand="1">
<eb:From>
<eb:PartyId eb:type="URI">Sabre_API</eb:PartyId>
</eb:From>
<eb:To>
<eb:PartyId eb:type="URI">Agency</eb:PartyId>
</eb:To>
<eb:ConversationId>2021.01.DevStudio</eb:ConversationId>
<eb:Service eb:type="sabreXML">Session</eb:Service>
<eb:Action>TokenCreateRS</eb:Action>
<eb:MessageData>
<eb:MessageId>1913771794839350290</eb:MessageId>
<eb:Timestamp>2023-02-23T22:04:43</eb:Timestamp>
</eb:MessageData>
</eb:MessageHeader>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:BinarySecurityToken valueType="String" EncodingType="wsse:Base64Binary">T1RLAQLASo74A7olKG7QnepeFqs19UHX+0Cds9QiDZoYfu677xC3Vkr9a+OcQhutjPL4atVMAADQRtHIXdehGg/0OVuPdia/0cM233jFDvyJJHgJHC3o8gV2ssS63b4Y0lgCG59SiG4tmEcqAXcYAMlnq+wJ4TfsOIDFwYdP+D0peSEFBM/m3EyOUqc4idJ+vO4S7xENCeQ7UX4YVKjVLJs788omPDbSIRNo85KQ5QxRprldV0jucJpAtbNfs1DrMHFqNIPyg0CpVpgXILkFx0azkcAuvmbHMHLqqO13WJEOhsG0KDBhBhRn8CwoCgD9foXL24W6yGu8Ecm0Fzvb/MuAjuYm9s48yg**</wsse:BinarySecurityToken>
</wsse:Security>
</soap-env:Header>
<soap-env:Body>
<sws:TokenCreateRS xmlns:sws="http://webservices.sabre.com" Version="1.0.0">
<sws:Success/>
</sws:TokenCreateRS>
</soap-env:Body> </soap-env:Envelope>
为了解析上面的XML,我最初尝试使用simplexml_load_String,但它给出了一个空响应。
然后我尝试使用下面的代码DOM方法,这里考虑**$response-〉Data**是上面的XML。
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadXML($response->Data);
$dom->formatOutput = true;
$XMLContent = $dom->saveXML();
它再次给出以下输出:
<!--?xml version="1.0" encoding="UTF-8"?-->
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:header>
<eb:messageheader xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" eb:version="1.0" soap-env:mustunderstand="1">
<eb:from>
<eb:partyid eb:type="URI">Sabre_API</eb:partyid>
</eb:from>
<eb:to>
<eb:partyid eb:type="URI">Agency</eb:partyid>
</eb:to>
<eb:conversationid>2021.01.DevStudio</eb:conversationid>
<eb:service eb:type="sabreXML">Session</eb:service>
<eb:action>TokenCreateRS</eb:action>
<eb:messagedata>
<eb:messageid>1002038859236010450</eb:messageid>
<eb:timestamp>2023-02-23T23:52:03</eb:timestamp>
</eb:messagedata>
</eb:messageheader>
<wsse:security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:binarysecuritytoken valuetype="String" encodingtype="wsse:Base64Binary">T1RLAQJZqih4+TYQmYCcdj42lcej5nckNWdo6WNb8edNl3xNtxAkqmu2YKjKki1OKQ7B3HK3AADQCGiRWrlzFPM0KB4foAOsSF+I+5eXE32uQ23LLd+hOduY2BCJYqPw7CvwCJ/LfNjy3P+QyvClvu6ysctC3a0GjmixDPDqCIckcXPb+XDFyYhR5G5QzQjch/Eax25koLnNvfN8rlvjNq+ENJmaV17wP43GLo1pzd19d9HGMn1VgjrJiVGWAb1ezyeiFNAd1VuBD2lAmdlo4jvZJzAS/fklZvwNFbKME64YpaFRptoLz0FKmz47y1TVYFtV6TZxbKirP3PDms0aGlItbJ4apPSB2Q**</wsse:binarysecuritytoken>
</wsse:security> </soap-env:header> <soap-env:body>
<sws:tokencreaters xmlns:sws="http://webservices.sabre.com" version="1.0.0">
<sws:success>
</sws:success></sws:tokencreaters> </soap-env:body> </soap-env:envelope>
因此,我计划从NODE获取数据,如下所示
$XML内容-〉按标记名获取元素('soap-env:header')-〉项目(0)-〉节点值);
但它没有给我一个节点值,而是开始给我错误。
我只想获取节点wsse:binarysecuritytoken
中的数据
有人经历过这样的事吗?
你能帮我一下吗?
更新也尝试跟踪,但仍然没有帮助
$domDocument = new DOMDocument();
$domDocument->loadXML($XMLContent);
$carriers=array();
$results=$domDocument->getElementsByTagName("wsse:Security");
foreach($results as $result)
{
foreach($result->childNodes as $node)
{
if($node instanceof DOMElement)
{
array_push($carriers, $node->textContent);
}
}
}
var_dump($carriers);
2条答案
按热度按时间sqyvllje1#
这是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
)。DOMXpath::evaluate()
允许使用返回节点列表和标量值的Xpath表达式。如果将节点列表(由位置路径指定)强制转换为字符串,它将返回第一个节点的文本内容或空字符串。hts6caw32#
好了,终于花了几个小时,我得到了!我不得不修改根据标签名称如下,在大多数家长我不得不使用soap-env而不是SOAP。