我有一个使用以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>
如果来自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>
是什么导致此异常,并且有解决该异常的方法而又不能更改Web服务本身?
最佳答案
我不知道是什么导致了错误,但是的,有一种解决方法。您可以使用RIO_AfterExecute()处理函数来修改SOAPResponse,以将XML更改为“使其适合”。这是一种丑陋的“更大的锤子”方法,但最终它使您可以摆弄数据以解决各种问题。
查看您的两个示例,我尝试使用stringreplace将'xsd:anyType [] [1]'替换为'xsd:anyType [] [3]'。如果这不起作用,请尝试注入(inject)另一组具有空值的数据,以使其看起来不仅有一个空值。
您将需要一个RIO对象,然后将其连接到这样的处理程序:
MyRIO.OnAfterExecute := self.RIO_AfterExecute;
就我而言,“自我”是指我围绕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;