PHP SoapClient:设置一个没有前缀的命名空间



我正在使用PHP的SoapClient使用WSDL SOAP服务。以下是WSDL的相关部分:https://gist.github.com/jurchiks/03771c0b85683969bc48711e56693919

生成的XML包含以下命名空间定义:

<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="WebApplicationImport"
....>

并且来自这个ns1名称空间的元素都以ns1:elementName为前缀。

服务提供者说这是错误的,他们希望这些元素没有前缀,即使WSDL定义了一个需求:xmlns:tns="WebApplicationImport" elementFormDefault="qualified"

一种解决方案是在发送XML之前执行以下操作:$xml = str_replace(':ns1', '', $xml);。这是有效的,但显然是一个黑客,我不喜欢黑客。

有没有一种方法可以告诉SoapClient将特定的命名空间作为默认名称空间/不作为前缀进行处理?我希望在生成信封的其余部分之前实现<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="WebApplicationImport">,理论上,这将确保该命名空间中的所有元素也不固定。对我来说,这似乎是一个正确有效的解决方案

WebApplicationImport不是有效的URI。因此它不是一个有效的命名空间。所以WSDL和XML实际上是无效的。某些解析器可能会容忍类似的名称空间,但它应该是类似urn:WebApplicationImporthttp://example.com/ns/WebApplicationImport的名称空间。

通过删除前缀,您将元素放入当前默认名称空间,在您的情况下,这应该是空/非名称空间。

有趣的是,PHP DOM在前缀的名称空间定义中允许它,但在默认名称空间中不允许:

$document = new DOMDocument();
$document->loadXML(
'<foo xmlns="WebApplicationImport"/>'
);

输出:

Notice: DOMDocument::loadXML(): xmlns: URI WebApplicationImport is not absolute in Entity

因此,根据服务提供商使用的解析器,它可能会为作为命名空间URI的WebApplicationImport抛出错误。

您应该删除/修复WSDL中的命名空间。如果您修复了它,那么服务提供商必须调整他的逻辑以使用新的名称空间。

前缀只是实际命名空间URI的别名。以下3个示例都可以读作{urn:example}foo:

  • <foo xmlns="urn:example"/>
  • <ns1:foo xmlns:ns1="urn:example"/>
  • <f:foo xmlns:f="urn:example"/>

我遇到了同样的问题,但在Java中,供应商不接受xmlns属性中的ns1。如果您想添加xmlns属性但没有ns1前缀,可以添加以下代码并进行检查。

声明SOAP标头元素:

soapHeader = new SOAPHeaderElement("", "HeaderElementName");
soapHeader.addAttribute("", "xmlns", "url");

最新更新