Sam*_*m M 5 delphi web-services delphi-xe
我有一个使用以Cold Fusion编写的Web服务的Delphi XE应用程序(我无法控制该服务的输出格式)。我在Delphi中使用WSDL Importer创建了用于调用Web服务的单元。我在Delphi中遇到一个异常,说“元素“数据”不包含单个文本节点”。
当我得到异常时,从Web服务返回的XML的相关部分是这样的:
<data soapenc:arrayType="xsd:anyType[][1]" xsi:type="soapenc:Array">
<data soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
<data xsi:type="soapenc:string">6490</data>
<data xsi:type="soapenc:string">Other Expense</data>
</data>
</data>
Run Code Online (Sandbox Code Playgroud)
如果来自Web服务的XML包含多个<data>子级,则不会发生异常。
<data soapenc:arrayType="xsd:anyType[][3]" xsi:type="soapenc:Array">
<data soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
<data xsi:type="soapenc:string">2600</data>
<data xsi:type="soapenc:string">Deferred Revenue</data>
</data>
<data soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
<data xsi:type="soapenc:string">4120</data>
<data xsi:type="soapenc:string">Non-Credit Income</data>
</data>
<data soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
<data xsi:type="soapenc:string">6490</data>
<data xsi:type="soapenc:string">Other Expense</data>
</data>
</data>
Run Code Online (Sandbox Code Playgroud)
是什么导致此异常,并且有解决该异常的方法而又不能更改Web服务本身?
我不知道是什么导致了这个错误,但是是的,有一种解决方法。您可以使用 RIO_AfterExecute() 处理程序来修改 SOAPResponse,以更改 XML 以“使其适合”。这是一种丑陋的“更大的锤子”方法,但它最终可以让你摆弄数据来解决各种问题。
看看您的两个示例,我尝试使用 stringreplace 将 'xsd:anyType[][1]' 替换为 'xsd:anyType[][3]'。如果这不起作用,请尝试注入另一组带有空值的数据,以使其看起来不只有一个。
您需要一个 RIO 对象,然后将其连接到处理程序,如下所示:
MyRIO.OnAfterExecute := self.RIO_AfterExecute;
Run Code Online (Sandbox Code Playgroud)
就我而言,“self”指的是我围绕 SOAP 内容编写的类。
当你处理完请求后,请务必将你的位置设置回 0。
这是一些未经测试的代码:
procedure MyWrapper.RIO_AfterExecute(const MethodName: string; SOAPResponse: TStream);
var
SL : TStringList;
begin
// do stuff with the SOAPResponse here.
// It's a stream, so I like to load it into a stringlist
// ex:
SL := TStringList.Create;
try
SOAPResponse.Position := 0;
SL.LoadFromSTream(SOAPREsponse);
// fiddle with stringreplace here, to doctor up the SL.text.
SOAPResponse.Position := 0;
SOAPResponse.size := length(SL.Text);
SL.SaveToStream(SOAPResponse);
finally
SL.free;
end;
end;
Run Code Online (Sandbox Code Playgroud)