Как я могу установить атрибуты для элементов SOAP в Delphi? - PullRequest
3 голосов
/ 11 мая 2009

В запросе клиента SOAP заголовку нужна эта строка:

<NS2:Header Name="Foo">Bar<NS2:Header>

Итак, я написал класс, который имеет два строковых свойства:

  • Свойство Content - для значения элемента ("Bar")
  • Свойство Name - для значения атрибута («Foo»)

Флаг AS_ATTRIBUTE свойства Name должен указывать, что это «атрибут» XML.

   Header = class(TSoapHeader)
   private
     FContent: string;
     FName: string;
   published
     property Content: string read FContent write FContent;
     property Name: string read FName write FName stored AS_ATTRIBUTE;
   end;

и зарегистрируйтесь с

   RemClassRegistry.RegisterXSClass(Header, MY_URI);
   RemClassRegistry.RegisterSerializeOptions(Header, [xoLiteralParam, 
xoSimpleTypeWrapper]);

Параметр xoLiteralTypWrapper указывает, что класс должен только «обернуть» значение свойства Content в элементе и не добавлять для него вложенный элемент.

Для Name: = "Foo" и Content: = "Bar" это будет XML-код результата в запросе SOAP:

<NS2:Header Name="Foo">
   <Content xsi:type="xsd:string">Bar</Content>
</NS2:Header>

Атрибут находится в правильном месте, но значение содержимого находится во вложенном теге, которого здесь быть не должно. Если я удалю свойство Name из определения класса, свойство Content будет выглядеть как содержимое элемента, например:

<NS2:Header>Bar</NS2:Header>

Это похоже на конфликт между двумя требованиями - если у меня есть атрибут, я не получу стиль xoSimpleTypeWrapper.

1 Ответ

3 голосов
/ 07 июня 2009

Я не пробовал это, так что это предположение. Попробуйте переопределить методы ObjectToSOAP и SOAPToObject. В файле справки написано

Переопределите ObjectToSOAP, чтобы настроить как ваше приложение преобразует TSOAPHeader потомок своего SOAP представление.

Опять же, я не пробовал это на компиляторе, но это может выглядеть так:

function Header.ObjectToSOAP(RootNode, ParentNode: IXMLNode; 
  const ObjConverter: IObjConverter; const Name, URI: InvString; 
  ObjConvOpts: TObjectConvertOptions; out RefID: InvString): IXMLNode;  
begin 
  ObjConvOpts := ObjConvOpts + [ocoDontSerializeProps]; 
  Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, Name, URI, ObjConvOpts, RefID); 
  Result.Text := FContent; 
  Result.Attributes['Name'] := FName;
end; 
...