2009-04-11 23 views
10

Tôi có XML xấu xí này có rất nhiều không gian tên trên đó, khi tôi cố gắng tải nó bằng simpleXML nếu tôi cho biết không gian tên đầu tiên tôi nhận được đối tượng xml, nhưng các thẻ sau với các không gian tên khác sẽ không đưa nó vào đối tượng.phân tích cú pháp XML bằng SimpleXML có nhiều không gian tên

Tôi làm cách nào để phân tích cú pháp XML này?

<?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 cố gắng để phân tích nó với đoạn mã sau

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

nhưng đối tượng $ xml sẽ chỉ chứa những điều sau

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

    [Body] => SimpleXMLElement Object 
     (
     ) 

) 

Trả lời

28

Tôi nghĩ rằng bạn cần phải đăng ký namespacing và truy cập với XPath. Một cái gì đó như sau sẽ giúp bạn đi (tôi đã không có cơ sở để kiểm tra điều này).

$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'); 

Sau đó, bạn có thể làm điều gì đó như:

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

Bạn có thể không cần phải đăng ký các không gian tên, suy nghĩ về nó, vì họ là alredy hiện diện trong XML. Không chắc chắn về điều này mặc dù, sẽ cần phải kiểm tra.

Hy vọng điều này sẽ hữu ích.

+1

Đơn giản chỉ cần Brillian bạn không chỉ giúp tôi giải quyết vấn đề của tôi mà còn làm sáng tỏ cách thức xpath làm việc :) cảm ơn! – perrohunter

+0

Không cần chuyển sang XPath chỉ vì bạn đang sử dụng không gian tên. – IMSoP

+0

Nếu bạn đang sử dụng XPath, thì bạn cần phải đăng ký không gian tên một cách rõ ràng như trong mã của bạn ở trên, nếu không xảy ra lỗi. – Bobulous

0

Đó là phong bì xà phòng. Bạn có thể muốn sử dụng một soap-client để trừu tượng hóa tất cả các phân tích cú pháp xml. PHP comes with a rather good soap-client được bao gồm làm mặc định.

7

1) Không sử dụng print_r và bạn bè để xem nội dung "trong" đối tượng SimpleXML là gì. Xem https://github.com/IMSoP/simplexml_debug để biết giải thích và các lựa chọn thay thế.

2) Hỗ trợ không gian tên trong SimpleXML được cung cấp bởi các phương pháp ->children()->attributes().

Ví dụ, bạn có thể nhận được các PartyId của Từ nút như thế này:

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

Đây là bình luận hữu ích nhất đối với tôi, tốt mà bạn chỉ ra rằng print_r vv không hoạt động và cung cấp một liên kết đến simplexml_debug, đạo cụ! –

+0

Các chức năng gỡ lỗi này thực sự hữu ích cho những người mới làm quen với điều này. – xdbas

-1

Hãy thử điều này

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

    var_dump($soap_client->__getFunctions()); 

Để cụ thể hơn read here

0

Đối với bất cứ ai khác mà đi qua tôi này trầy xước đầu tôi cố gắng trả lại dữ liệu chính xác và mặc dù câu trả lời hàng đầu rất gần nhưng tôi vẫn mất một lúc để tìm câu trả lời. Cuối cùng, sử dụng trang này để trợ giúp: https://www.w3schools.com/php/func_simplexml_registerxpathnamespace.asp

Tôi tin rằng vòng lặp có thể truy cập trực tiếp vào những gì bạn cần. ví dụ:

foreach($xml->xpath('//eb:CPAId') as $header) 
{ 
    echo $header; // Should output 'something'. 
} 
Các vấn đề liên quan