首页 > 解决方案 > SOAPUI SOAP 模拟错误:前缀不能以 XML 开头:XMLSchema-instance

问题描述

我正在尝试模拟 Vmware vSphere Vcenter SOAP API 的一些场景(此处下载的 VMware-vSphereSDK-6.5.0:https ://my.vmware.com/web/vmware/details?productId=614&downloadGroup=VS-MGMT-SDK65 )。

我可以模拟几个 API 操作,直到遇到问题,因为 WSDL 引用了一个显然由于以下语句而生成错误的命名空间:

<selectSet XMLSchema-instance:type="TraversalSpec" xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance">

这是抛出的异常

ERROR:com.eviware.soapui.impl.wsdl.mock.DispatchException:   org.apache.xmlbeans.XmlException: error: Prefix can't begin with XML: XMLSchema-instance
   com.eviware.soapui.impl.wsdl.mock.DispatchException: org.apache.xmlbeans.XmlException: error: Prefix can't begin with XML: XMLSchema-instance
at com.eviware.soapui.impl.wsdl.mock.WsdlMockDispatcher.dispatchPostRequest(WsdlMockDispatcher.java:242)
at com.eviware.soapui.impl.wsdl.mock.WsdlMockDispatcher.dispatchRequest(WsdlMockDispatcher.java:114)
at com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner.dispatchRequest(WsdlMockRunner.java:144)
at com.eviware.soapui.monitor.JettyMockEngine$ServerHandler.handle(JettyMockEngine.java:604)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.jetty.security.SslSocketConnector$SslConnection.run(SslSocketConnector.java:713)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.xmlbeans.XmlException: error: Prefix can't begin with XML: XMLSchema-instance
at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3474)
at org.apache.xmlbeans.impl.store.Locale.parse(Locale.java:712)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:696)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:683)
at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:208)
at org.apache.xmlbeans.XmlObject$Factory.parse(XmlObject.java:633)
at com.eviware.soapui.support.xml.XmlUtils.createXmlObject(XmlUtils.java:183)
at com.eviware.soapui.impl.support.AbstractMockRequest.getRequestXmlObject(AbstractMockRequest.java:297)
at com.eviware.soapui.impl.wsdl.mock.WsdlMockDispatcher.dispatchPostRequest(WsdlMockDispatcher.java:193)
... 16 more

以下是在 SOAP UI 上失败的 API 操作请求的全文(显然适用于 vSphere):

'<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
    <RetrieveProperties xmlns="urn:vim25">
        <_this type="PropertyCollector">propertyCollector</_this>
        <specSet>
            <propSet>
                <type>Folder</type>
                <pathSet>name</pathSet>
                <pathSet>childType</pathSet>
            </propSet>
            <propSet>
                <type>Datacenter</type>
                <pathSet>name</pathSet>
            </propSet>
            <propSet>
                <type>VirtualMachine</type>
                <pathSet>name</pathSet>
            </propSet>
            <propSet>
                <type>Network</type>
                <pathSet>name</pathSet>
            </propSet>
            <propSet>
                <type>ComputeResource</type>
                <pathSet>name</pathSet>
                <pathSet>resourcePool</pathSet>
            </propSet>
            <propSet>
                <type>ClusterComputeResource</type>
                <pathSet>name</pathSet>
                <pathSet>resourcePool</pathSet>
            </propSet>
            <propSet>
                <type>Datastore</type>
                <pathSet>name</pathSet>
            </propSet>
            <objectSet>
                <obj type="Folder">group-d1</obj>
                <skip>true</skip>
                <selectSet XMLSchema-instance:type="TraversalSpec" xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance">
                    <type>Folder</type>
                    <path>childEntity</path>
                    <skip>false</skip>
                </selectSet>
            </objectSet>
        </specSet>
    </RetrieveProperties>
</Body>

我的观点是,这是对与检查 xml 命名空间正确语法相关的 XML 规范的解释,该语法已在该错误报告(在 jdom 上下文中)中讨论并明显修复:https ://github.com/hunterhacker/jdom/issues/ 126

实际上,在他们的 api 中,vmware 人员引用了一个以 XML(XMLSchema-Instance)开头的命名空间,也许不应该(我没有足够的 XML 专家来判断)但是规范https://www.w3.org/TR /REC-xml-names/#xmlReserved似乎清楚地说这不能被视为错误。

欢迎任何关于如何绕过(或修复)此问题的想法。多谢。

标签: xmlunit-testingsoapsoapuivmware

解决方案


XML 命名空间建议的第一版简单地说,以“xml”开头的前缀是为将来的规范保留的。它没有说明如果遇到此类前缀,解析器应该做什么。

一些产品通过拒绝包含此类前缀的文档来解释该规则。这会混淆保留它们的意图,因为如果任何新标准采用这样的名称,使用该名称的文档将无法与旧软件一起使用。因此,在 XML 命名空间的第二版中,该规则的含义得到了澄清:应用程序不应使用此类名称,但解析器不应拒绝它们。

但这当然为时已晚。软件已经存在,对规则有不同的解释,其中一些还没有更新。

如何解决问题?您要么必须更改文档,要么更改软件。我会尝试通过更改前缀的 XSLT 转换来放置文档。


推荐阅读