我有一个Delphi XE应用程序,它使用Cold Fusion编写的Web服务(我无法控制服务的输出格式)。我使用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服务本身?
答案 0 :(得分:4)
我不知道导致错误的原因是什么,但是,有一种解决方法。您可以使用RIO_AfterExecute()处理程序来修改SOAPResponse,以将XML更改为“使其适合”。这是一种丑陋的,“更大锤子”的方法,但它最终会让你摆弄数据以解决各种各样的问题。
看看你的两个例子,我尝试使用stringreplace用'xsd:anyType [] [3]'替换'xsd:anyType [] [1]'。如果这不起作用,请尝试使用空值注入另一组数据,以使其看起来不仅仅是一个。
你需要一个RIO对象,然后你把它连接到这样的处理程序:
MyRIO.OnAfterExecute := self.RIO_AfterExecute;
就我而言,“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;
答案 1 :(得分:2)
仅供参考,我今天遇到了同样的问题,经过几个小时的搜索,我发现了问题。事实是,WSDL导入器错误地将某些类型映射到字符串,这导致TXMLDocument被指示在没有文本节点的情况下读取文本节点! 所以定义为字符串(或字符串数组)的任何类型都可能是错误的......
到OP:检查导入单元中soapenc:Array类型的定义。
答案 2 :(得分:1)
必须是您的Delphi xml阅读代码中的错误。它有效的事实有时是偶然的。根据您正在使用的组件,浏览XML会有所不同。
我相信这些会对你有所帮助
Libraries and tutorials for XML in Delphi
Where is a tutorial for using XML with Delphi?
如果发布Delphi XML处理代码,我们可以进一步深入研究。