2009-04-11 7 views
10

Ich habe dieses hässliche XML, das viele Namespaces hat, wenn ich versuche, es mit SimpleXML zu laden, wenn ich den ersten Namespace gebe ich ein XML-Objekt, aber folgende Tags mit anderen Namespaces würde es nicht zum Objekt schaffen.parse ein XML mit SimpleXML, das mehrere Namespaces hat

Wie kann ich dieses XML analysieren?

<?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">wscompany.com</eb:PartyId> 
      </eb:From> 
      <eb:To> 
       <eb:PartyId eb:type="URI">mysite.com</eb:PartyId> 
      </eb:To> 
      <eb:CPAId>something</eb:CPAId> 
      <eb:ConversationId>moredata.com</eb:ConversationId> 
      <eb:Service eb:type="compXML">theservice</eb:Service> 
      <eb:Action>theaction</eb:Action> 
      <eb:MessageData> 
       <eb:MessageId>a certain messageid</eb:MessageId> 
       <eb:Timestamp>2009-04-11T18:43:58</eb:Timestamp> 
       <eb:RefToMessageId>mid:areference</eb:RefToMessageId> 
      </eb:MessageData> 
     </eb:MessageHeader> 
     <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"> 
      <wsse:BinarySecurityToken valueType="String" EncodingType="wsse:Base64Binary">an impresive binary security toekn</wsse:BinarySecurityToken> 
     </wsse:Security> 
    </soap-env:Header> 
    <soap-env:Body> 
     <SessionCreateRS xmlns="http://www.opentravel.org/OTA/2002/11" version="1" status="Approved"> 
      <ConversationId>the goodbye token</ConversationId> 
     </SessionCreateRS> 
    </soap-env:Body> 
</soap-env:Envelope> 

im Versuch, es mit dem folgenden Code würde nur

<?php 
$xml = simplexml_load_string($res,NULL,NULL,"http://schemas.xmlsoap.org/soap/envelope/"); 
?> 

aber das $ XML-Objekt zu analysieren enthalten die folgenden

SimpleXMLElement Object 
(
    [Header] => SimpleXMLElement Object 
     (
     ) 

    [Body] => SimpleXMLElement Object 
     (
     ) 

) 

Antwort

28

Ich glaube, Sie brauchen das Namespacing und den Zugang zu registrieren mit XPath. Etwas wie das Folgende sollte dich in Gang bringen (ich habe nicht die Möglichkeit, dies zu testen).

$xml = simplexml_load_string($res, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/"); 
$xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/'); 
$xml->registerXPathNamespace('eb', 'http://www.ebxml.org/namespaces/messageHeader'); 
$xml->registerXPathNamespace('wsse', 'http://schemas.xmlsoap.org/ws/2002/12/secext'); 

Dann können Sie so etwas wie:

foreach($xml->xpath('//eb:MessageHeader') as $header) 
{ 
    var_export($header->xpath('//eb:CPAId')); // Should output 'something'. 
} 

Sie können nicht die Namespacing registrieren müssen, darüber nachzudenken, wie sie in der XML alredy vorhanden sind. Ich bin mir nicht sicher, müsste aber testen.

Hoffe, das hilft.

+1

einfach Brillian Sie nicht nur mir geholfen, mein Problem zu lösen, sondern auch geklärt, wie XPath :) Dank funktionierte! – perrohunter

+0

Es ist nicht erforderlich, zu XPath zu wechseln, nur weil Sie Namespaces verwenden. – IMSoP

+0

Wenn Sie XPath verwenden, müssen Sie die Namespaces explizit wie oben in Ihrem Code registrieren, andernfalls tritt ein Fehler auf. – Bobulous

7

1) Verwenden Sie nicht print_r und Freunde, um zu sehen, was in einem SimpleXML-Objekt "in" ist. Erläuterungen und Alternativen finden Sie unter https://github.com/IMSoP/simplexml_debug.

2) Die Namespace-Unterstützung in SimpleXML wird von den Methoden ->children() und ->attributes() bereitgestellt.

Zum Beispiel könnten Sie die PartyID von der Von-Knoten wie folgt erhalten:

$from_party = (string)$xml->children('soap-env', true)->Header->children('eb', true)->MessageHeader->From->PartyId; 
+0

verwirrt Dies war der nützlichste Kommentar für mich, gut, dass Sie darauf hinweisen, dass print_r usw. nicht funktionieren und einen Link zu simplexml_debug, Requisiten bieten! –

+0

Diese Debug-Funktionen sind wirklich hilfreich für Leute, die neu sind. – xdbas

-1

dieses Versuchen

$soap_url = 'http://path/wsdl/somefile.wsdl'; 
    $soap_client = new SoapClient($soap_url); 

    var_dump($soap_client->__getFunctions()); 

Weitere Einzelheiten read here

0

Für alle anderen, die sich über dieses I kommt Ich kratzte mich am Kopf und versuchte, die richtigen Daten zurückzugeben. Obwohl die Antwort sehr knapp war, brauchte ich noch eine Weile, um die Antwort zu finden. Schließlich diese Seite verwendet, um zu helfen: https://www.w3schools.com/php/func_simplexml_registerxpathnamespace.asp

Ich glaube, die for-Schleife kann direkt zugreifen, was Sie brauchen. das heißt

foreach($xml->xpath('//eb:CPAId') as $header) 
{ 
    echo $header; // Should output 'something'. 
}