Что вызывает эту ошибку при использовании веб-службы? - PullRequest
4 голосов
/ 25 августа 2011

У меня есть приложение Delphi XE, которое использует веб-сервис, написанный на Cold Fusion (у меня нет контроля над форматом вывода сервиса).Я использовал импортер WSDL в Delphi, чтобы создать свой модуль для вызовов веб-службы.Я сталкиваюсь с ситуациями, когда в Delphi я получаю исключение, в котором говорится, что данные «Элемент» не содержат ни одного текстового узла ».

Соответствующая часть 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>

Если 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>

Что вызывает это исключение и существует лиобойтись без возможности изменить сам веб-сервис?

Ответы [ 3 ]

4 голосов
/ 25 августа 2011

Я не знаю, что является причиной ошибки, но да, есть способ обойти это. Вы можете использовать обработчик RIO_AfterExecute (), чтобы изменить SOAPResponse, чтобы изменить XML, чтобы «подогнать его». Это уродливый, «больший молоток» подход, но в конечном итоге он позволяет вам манипулировать данными, чтобы обойти все виды проблем.
Глядя на ваши два примера, я бы попробовал использовать stringreplace для замены 'xsd: anyType [] [1]' на 'xsd: anyType [] [3]'. Если это не сработает, попробуйте ввести другой набор данных с пустыми значениями, чтобы создать впечатление, что он не один.

Вам понадобится объект 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;
2 голосов
/ 19 января 2012

Просто для справки, я столкнулся с той же проблемой сегодня, и после нескольких часов поиска я нашел проблему.Дело в том, что импортер WSDL неправильно отображает определенные типы в строку, что приводит к тому, что TXMLDocument получает указание прочитать текстовый узел, пока его нет!Таким образом, любой тип, определенный как строка (или массив строк), может быть неправильным ...

Для OP: проверьте определение типа soapenc: Array в импортируемой единице.

1 голос
/ 25 августа 2011

Там должно быть ошибка в вашем коде чтения Delphi xml. Факт, что это работает иногда, является второстепенным. Навигация по XML отличается в зависимости от используемого вами компонента.

Я верю, что это поможет вам

Библиотеки и учебные пособия по XML в Delphi

Где находится учебник по использованию XML с Delphi?

Если вы опубликуете код обработки Delphi XML, мы можем углубиться в него.

...