导入命名空间的 Eclipse WSDL 验证错误

Eclipse WSDL Validation Error with Imported Namespaces

我从组织中的服务团队收到了一个非内联 WSDL 文件,在将他们的所有 XSD 添加到 Eclipse 中的 XML 目录后,我找到了他们的主要 WSDL 文件不验证。它似乎没有找到 <wsdl:import> 中定义的 <wsdl:message> 元素。验证错误是这样的:

The fault element is referencing an undefined message 'serviceFault'. Check that the message name and namespace are correct and that the message has been defined.

同一文件夹中的所有文件路径都是相对的。这是一个重新创建验证错误的小测试示例:

test.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema 
    targetNamespace="http://www.example.org/test" xmlns="http://www.example.org/test"
    elementFormDefault="qualified" attributeFormDefault="unqualified"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:ibmSchExtn="http://www.ibm.com/schema/extensions">

    <xsd:complexType name="ServiceFaultType">
        <xsd:sequence>
            <xsd:element name="code" type="xsd:string" />
            <xsd:element name="message" type="xsd:string" />
            <xsd:element minOccurs="0" name="detail" type="xsd:string" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element ibmSchExtn:docRoot="true" name="serviceFault"
        type="ServiceFaultType" />
</xsd:schema>

common.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    targetNamespace="http://www.example.org/test" xmlns="http://www.example.org/test"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:documentation>
        <wsdl:appinfo source="WMQI_APPINFO">
            <MRWSDLAppInfo xmlns="urn:xxx.xxx.xxxbank.com/common/service"
                imported="true" />
        </wsdl:appinfo>
    </wsdl:documentation>
    <wsdl:types>
        <xs:schema elementFormDefault="qualified">
            <xs:import namespace="http://www.example.org/test"
                schemaLocation="test.xsd" />
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="serviceFault">
        <wsdl:part element="serviceFault" name="fault" />
    </wsdl:message>
</wsdl:definitions>

test.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    targetNamespace="urn:testservice" xmlns="urn:testservice"
    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
    xmlns:ns="http://www.example.org/test"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">


    <wsdl:import namespace="http://www.example.org/test" location="common.wsdl"></wsdl:import>
    <wsdl:types>
        <xsd:schema targetNamespace="urn:testservice">
            <xsd:element name="NewOperation">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="in" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="NewOperationResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="out" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="NewOperationRequest">
        <wsdl:part element="NewOperation" name="parameters" />
    </wsdl:message>
    <wsdl:message name="NewOperationResponse">
        <wsdl:part element="NewOperationResponse" name="parameters" />
    </wsdl:message>
    <wsdl:portType name="test">
        <wsdl:operation name="NewOperation">
            <wsdl:input message="NewOperationRequest" />
            <wsdl:output message="NewOperationResponse" />
            <wsdl:fault message="ns:serviceFault" name="fault" />
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="testSOAP" type="test">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="NewOperation">
            <soap:operation soapAction="http://www.example.org/test/NewOperation" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="test">
        <wsdl:port binding="testSOAP" name="testSOAP">
            <soap:address location="http://www.example.org/" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

如果您将 test.xsd 添加到 Eclipse 中的 XML 目录,它会显示验证错误。他们坚持认为他们的 WSDL 或模式没有任何问题,并且 JAX-WS 似乎可以生成与 wsimport 很好的代理。此外,在与端点通信时,它似乎可以很好地编组和解组请求和响应。

这可能是 Eclipse 的 WSDL 验证中的错误吗?

编辑: 只是一个想法,尽管我还没有解决问题。我认为可能会发生的事情是 Eclipse 正在验证 test.xsd 的命名空间,但也在该命名空间中 common.wsdl 声明了它自己的元素。当 Eclipse 在 ns 命名空间中寻找这个常见的 ns:serviceFault 时,它显然不会在 test.xsd 中找到它。这让我觉得 Eclipse WSDL 验证在这里应该更智能一些,并识别 WSDL 导入并包括其中的所有内容以及在其 XML 目录中声明的模式。如果我在这里标记,我仍然不确定如何解决它。 Eclipse 是否有一个功能可以真正正确地验证这种类型的 WSDL 情况?

我自己创建了文件,并使用 Eclipse Luna 4.4.0Web Developer Tools 3.2.5 进行了测试。我将两个 .wsdl 文件放在同一个通用项目中,然后通过向导将 .xsd 导入到 XML 目录中。

当我验证每个文件时,Eclipse 没有找到任何 errors/warnings。当我从项目中删除 common.wsdl 文件时,我确实收到了您引用的错误消息,但这是预料之中的,因为它是在 test.wsdl 中导入的。我还尝试在 SoapUI 5.0.0 中使用 test.wsdl(从 Eclipse 目录)创建一个新的 SoapUI 项目,它也没有抱怨。

由于我无法重现该错误,我认为这很可能是您正在使用的特定 Eclipse 版本的错误或 Web 开发人员工具有问题。或者它可能是一些当地的废话,乍一看不会立即流行起来。再次确保 Eclipse 实际上将所有文件物理地放在文件系统的同一目录中。

看我的Eclipse配置的screenshot给大家对比一下,要不要换版本。

很高兴能够进一步帮助您,但至少我向您确认问题是本地的。祝你好运!


评论 1 后更新 1

最初,我通过 Import->XML->XML Catalog 导入了 test.xsd。现在我将 .xsd 移动到另一个文件系统位置并将其从项目中删除(因为否则它总是有效)。然后,我按照你的建议做了 (Window->Preferences->XML->XML catalog->User specified entries->Catalog Entry->From filesystem 键类型 = 尝试了命名空间名称架构位置 = http://www.example.org/test)。执行此操作后,我收到警告 Error reading .xsd file (pointing to the local directory of the project instead of the new location) 和多个错误,其中一个是你的。

如果我删除 common.wsdl 中的 schemaLocation="test.xsd" 属性并将 keytype 设置为 Namespace,那么 common.wsdl 可以正常工作并且没有错误,但是 test.wsdl 说:

错误元素正在引用未定义的消息 'serviceFault'。检查消息名称和命名空间是否正确,消息是否已定义。

我看到 common.wsdl 有两个具有相同命名空间名称的命名空间:xsxsd(“http://www.w3.org/2001/XMLSchema”)。这会导致错误吗?

更新 2

我进一步调查并发现 this wiki page,解释了如何使用 XML 目录和模式。根据它,这种行为有点意料之中:

Note : If your XML document specificed relative schema locations (e.g. 'foo.xsd' as show below) then an XML Schema can NOT be registered using "foo.xsd" as the Schema Location key. TODO: reference section below that describes why this is the case and how XML Catalog v1.1 provides a way to partially solve this. <xyz:foo xmln:xyz="http://www.example.org/foo/" xsi:schemaLocation="foo.xsd" ...

所以他们似乎知道这些相对路径存在问题。

然后我尝试在目录键和 schemaLocation 中使用完整的 URI,并且没有错误:

我会继续研究这个问题(我在讨论过类似主题的 Eclipse 论坛上发现 this thread),如果出现问题,我会 post 进行更新。