2011-12-28 39 views
9

Tôi đang viết lại dịch vụ web xà phòng từ .net sang php. theo mặc định, php là đem lại cho tôi thẻ mà trông như thế này:thay đổi tiền tố xà phòng trong php

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"><SOAP-ENV:Header><ns1:FindAllCategories/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:FindAllCategoriesResponse><ns1:FindAllCategoriesResult><ns1:ArtistCategoryDto> 

vv ...

nhưng tôi cần cái này:

<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><FindAllCategoriesResponse xmlns="http://tempuri.org/"><FindAllCategoriesResult><ArtistCategoryDto> 

này cũng tương tự như câu hỏi ở đây: PHP AND SOAP. Change envelope tuy nhiên Tôi muốn không hack nó theo cách anh ấy đã làm. Ngoài ra, tôi đang tạo ra một dịch vụ xà phòng sẽ được tiêu thụ bởi một ứng dụng iphone hiện có, không sử dụng PHP để tiêu thụ một dịch vụ xà phòng bằng cách sử dụng SoapClient. Ứng dụng iphone chỉ phân tích cú pháp xml thô và tôi không thể thay đổi ứng dụng iphone ngay bây giờ.

+1

Bạn có thể nói cụ thể những gì bạn không thích với giải pháp khác không? Nơi nào bạn thấy một shortcomming? Ngoài ra "Tôi chỉ cần điều này để làm việc" là khó thực hiện, bởi vì Iphone App rõ ràng là có một shortcomming. Có lẽ nó không phải là người duy nhất, vậy làm thế nào ai đó có thể trả lời câu hỏi của bạn nếu không đoán? – hakre

+0

Chắc chắn. Vì vậy, một vài vấn đề. Đầu tiên, tôi đang xây dựng một dịch vụ xà phòng, và ví dụ là sử dụng một khách hàng xà phòng. Tôi không sử dụng ứng dụng khách xà phòng php nào cả - ứng dụng là ứng dụng khách. Thứ hai, tôi không thích sử dụng RegEx để hack xml.Tôi muốn làm điều đó với một số api bản địa, hoặc nếu hoàn toàn cần thiết, bằng cách sử dụng một phân tích cú pháp xml để phân tích các không gian tên, nhưng tôi không biết làm thế nào để có được một tổ chức của phản ứng để phân tích cú pháp XML. Ứng dụng chắc chắn có một thiếu sót, bởi vì nó không sử dụng xà phòng theo cách nó được dự định. Nhưng cách nó được xây dựng bởi vì không có các trình phân tích cú pháp xà phòng tốt vào thời điểm đó. – fregas

Trả lời

5

Sau khi đọc lại những gì nó là bạn muốn và tìm kiếm thông qua các tài liệu php đây là giải pháp của tôi và một vài giả định rằng tôi đã

Giả

  • Nếu tôi m đúng, bạn biết rằng tiền tố SOAP chính nó không phải là vấn đề (bạn được phép sử dụng bất kỳ tiền tố nào miễn là tiền tố đó là nhất quán).
  • Chúng ta cần phải tạo ra một công việc xung quanh cho điều này ứng dụng Iphone cụ thể mà làm cho việc sử dụng một (xml) phân tích cú pháp mà hiện tại không thể được sửa đổi/nâng cấp bởi bạn

Ông muốn gì?

  1. Bạn muốn sử dụng một API bản địa để thay đổi tiền tố SOAP
  2. Bạn muốn nắm bắt những phản ứng SoapServer vì vậy bạn có thể thay đổi tiền tố SOAP trước khi nó đang được trả lại

Solution

  1. Hiện tại không có phương pháp API SoapServer gốc nào để thay đổi tiền tố SOAP
  2. Bạn có thể nắm bắt những phản ứng SoapServer và xử lý các phản ứng bằng cách regex hoặc xml parser xem ví dụ dưới đây
<?php 

// Create you parse function - Regex 
function SoapServerRegexParser($input) 
{ 
    // $input contains your XML Response 
    // Do str_replace or preg_replace 
    $request = preg_replace({do replace}); 

    //return modified output to client 
    return $request; 
} 

// OR create you parse function - Regex XML Parser 
function SoapServerXMLParser($input) 
{ 
    // $input contains your XML Response 
    // Use any xml parser that you would like 
    $xml = new DOMDocument(); 
    $xml->formatOutput = true; 
    $xml->preserveWhiteSpace = false; 
    $xml->loadXML($input); 
    //Do replacement have a looke at: DOMNode::replaceChild 

    //return modified output to client 
    return $xml->saveXML(); 
} 

// Make php buffer all output 
// Send all output to a callBack function 

// Replace 'SoapServerRegexParser' with the callback function name of choice 
ob_start('SoapServerRegexParser'); //buffer output and set callback function 

// Create SoapServer 
$server = new SoapServer('wsdlfile.wsdl'); 
$server->handle(); //Handle incoming request 
ob_end_flush(); //Release buffer, but send through callback function first 

?> 

này nên làm như lừa, tôi đã không tạo ra phần regex hoặc thay thế nút XLM thực tế nhưng tôi nghĩ bạn có thể tự mình làm điều đó

+0

Thực ra, tôi cần tiền tố không gian tên rất cụ thể. Ứng dụng iphone đang tìm kiếm chúng. Tuy nhiên, nếu tôi có thể thay đổi đầu ra trong bộ đệm theo cách bạn đang làm ở đây, tôi nghĩ rằng tôi tốt. Vì vậy, thay vì: ob_start ('SoapServerRegexParser'); Tôi sẽ sử dụng: SoapServerXMLParser '); ... nếu tôi muốn phân tích cú pháp bằng xml? – fregas

+0

Đúng vậy. Hãy xem http://nl2.php.net/manual/en/domnode.replacechild.php về cách thay thế một nút con. Nếu các chuỗi bạn đang tìm kiếm và bạn muốn thay thế chúng, tôi nghĩ việc sử dụng str_replace –

+0

rất dễ dàng - chỉ là những gì tôi cần để viết nhanh máy chủ xà phòng linh hoạt. – Olaf

0

Nếu bạn không muốn sử dụng cụm từ thông dụng, tôi đã thực hiện triển khai lớp nhanh này sử dụng DomXPath và DomDocument để dọn sạch XML và nối thêm thuộc tính không gian tên ở cấp nút.

<?php 

public BetterSoapClient extends SoapClient { 

    public function __construct($wsdl, $options = null) { 
     parent::__construct($wsdl, $options); 
    } 

    public function __doRequest($request, $location, $action, $version) { 

     $dom = new DOMDocument('1.0'); 

     // loads the SOAP request to the Document 
     $dom->loadXML($request); 

     // Create a XPath object 
     $path = new DOMXPath($dom); 

     // Search the nodes to fix 
     $nodesToFix = $path->query('//SOAP-ENV:Envelope/SOAP-ENV:Body/*', null, true); 

     // Remove unwanted namespaces 
     $this->fixNamespace($nodesToFix, 'ns1', 'http://tempuri.org/'); 

     // Save the modified SOAP request 
     $request = $dom->saveXML(); 

     return parent::__doRequest($request, $location, $action, $version); 
    } 

    public function fixNamespace(DOMNodeList $nodes, $namespace, $value) { 
     // Remove namespace from envelope 
     $nodes->item(0) 
       ->ownerDocument 
       ->firstChild 
       ->removeAttributeNS($value, $namespace); 

     //iterate through the node list and remove namespace 

     foreach ($nodes as $node) { 

      $nodeName = str_replace($namespace . ':', '', $node->nodeName); 
      $newNode = $node->ownerDocument->createElement($nodeName); 

      // Append namespace at the node level 
      $newNode->setAttribute('xmlns', $value); 

      // And replace former node 
      $node->parentNode->replaceChild($newNode, $node); 
     } 
    } 
} 
+0

điều này không giúp tôi. Tôi đang xây dựng một dịch vụ web xà phòng, bằng cách sử dụng SoapServer, không tiêu thụ một dịch vụ khác bằng cách sử dụng SoapClient. Tôi đã sửa đổi bài viết gốc để làm cho điều này rõ ràng hơn, mặc dù tôi đã đề cập ban đầu nó và cũng có trong các ý kiến. – fregas

Các vấn đề liên quan