【问题标题】:PHP SoapClient: set a namespace without prefixPHP SoapClient:设置没有前缀的命名空间
【发布时间】:2019-10-24 09:57:33
【问题描述】:

我正在使用 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);。这可行,但显然是一种 hack,而且我不喜欢 hack。

有没有办法告诉SoapClient 将特定命名空间作为默认值/不作为前缀处理?我想要实现的是&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="WebApplicationImport"&gt;,然后再生成信封的其余部分,理论上,这将确保该命名空间中的所有元素也没有前缀。 这对我来说似乎是正确有效的解决方案。

【问题讨论】:

    标签: php xml soap wsdl


    【解决方案1】:

    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
    

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

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

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

    • &lt;foo xmlns="urn:example"/&gt;
    • &lt;ns1:foo xmlns:ns1="urn:example"/&gt;
    • &lt;f:foo xmlns:f="urn:example"/&gt;

    【讨论】:

    • 检查我添加的 WSDL 并重试。问题不在于验证 - WSDL 工作正常;问题是他们的服务似乎在使用一些破坏的代码来解析请求,并且他们无法读取命名空间元素或其他内容,因此删除了前缀。
    猜你喜欢
    • 2023-03-29
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多