change soap prefixes in php

前端 未结 2 390
小鲜肉
小鲜肉 2020-12-11 16:16

i\'m rewriting a soap web service from .net to php. by default, php is giving me tags that look like this:



        
相关标签:
2条回答
  • 2020-12-11 16:50

    After re-reading what it is you want and searching through the php documentation here is my solution and a couple of assumptions that I made

    Assumptions

    • If I'm correct you are aware that the SOAP prefix itself isn't the issue (you are allowed to use any prefix as long as it is consistent).
    • We need to create a work-around for this specific Iphone app that makes use of a (xml) parser that currently can not be modified/upgraded by you

    What do you want?

    1. You would like to use a native API to alter the SOAP prefix
    2. You want to catch the SoapServer response so you can alter the SOAP prefix before it is being returned

    Solution

    1. Currently there is no native SoapServer API method to alter the SOAP prefix
    2. You can catch the SoapServer response and process the response either by regex or xml parser see example below
    <?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
    
    ?>
    

    This should do the trick, I haven't created the regex part or the actual xlm node replacement but I figure you can do that yourself

    0 讨论(0)
  • 2020-12-11 17:17

    If you don't want to use Regular expressions, I've done this quick class implementation which uses DomXPath and DomDocument to cleanup the XML and append the namespace attribute at the node level.

    <?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 讨论(0)
提交回复
热议问题