我正在将.net的soap web服务重写为php。默认情况下,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>
等...
但我需要这个:
<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>
这与这里的问题类似:PHP AND SOAP. Change envelope但是我不想像他那样破解它。此外,我正在创建一个将由现有的iphone应用程序使用的soap服务,而不是使用PHP来使用SoapClient来使用soap服务。 iPhone应用程序只解析原始xml,我现在无法更改iPhone应用程序。
答案 0 :(得分:5)
重新阅读你想要的东西并在这里搜索php文档是我的解决方案和我做的几个假设
<强>假设强>
你想要什么?
<强>解决方案强>
<?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
?>
这应该可以解决问题,我没有创建正则表达式部分或实际的xlm节点替换,但我认为你可以自己做这个
答案 1 :(得分:1)
如果你不想使用正则表达式,我已经完成了这个快速类实现,它使用DomXPath和DomDocument来清理XML并在节点级别追加命名空间属性。
<?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);
}
}
}