Форум программистов, компьютерный форум, киберфорум
Delphi: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/230: Рейтинг темы: голосов - 230, средняя оценка - 4.58
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 2

SOAP клиент для web-сервиса npchk.nalog.ru

06.02.2015, 13:19. Показов 62439. Ответов 4

Студворк — интернет-сервис помощи студентам
Всем привет.

Возникла необходимость написать клиент для сервиса http://npchk.nalog.ru.
WSDL сервиса - http://npchk.nalog.ru/FNSNDSCAWS?wsdl
XSD-схемы: запрос - http://npchk.nalog.ru:80/FNSNDSCAWS?xsd=1
ответ - http://npchk.nalog.ru:80/FNSNDSCAWS?xsd=2

В программе SoapUI запрос выглядит следующим образом:
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://ws.unisoft/FNSNDSCAWS/Request">
   <soapenv:Header/>
   <soapenv:Body>
      <req:NdsRequest>
         <!--1 to 10000 repetitions:-->
         <req:NP INN="525202471833"/>
         <req:NP INN="525202471834"/>
      </req:NdsRequest>
   </soapenv:Body>
</soapenv:Envelope>

Ответ:
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <NdsResponse DTActFL="04.02.2015" DTActUL="04.02.2015" xmlns="http://ws.unisoft/FNSNDSCAWS/Response">
         <NP INN="525202471833" State="2"/>
         <NP INN="525202471834" State="4"/>
      </NdsResponse>
   </S:Body>
</S:Envelope>


Суть в том, что в запросе можно отправить ИНН и получить ответ, зарегистрирован этот ИНН или нет. Как видно в примере для каждого ИНН добавляется State со значением от 0 до 4.

Использую Delphi 7.
WSDL-importer сгенерировал такой код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : [url]http://npchk.nalog.ru:80/FNSNDSCAWS?wsdl[/url]
// Encoding : UTF-8
// Version  : 1.0
// (06.02.2015 11:31:58 - 1.33.2.5)
// ************************************************************************ //
 
unit FNSNDSCAWS;
 
interface
 
uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;
 
type
 
  // ************************************************************************ //
  // The following types, referred to in the WSDL document are not being represented
  // in this file. They are either aliases[@] of other types represented or were referred
  // to but never[!] declared in the document. The types from the latter category
  // typically map to predefined/known XML or Borland types; however, they could also 
  // indicate incorrect WSDL documents that failed to declare or import a schema type.
  // ************************************************************************ //
  // !:NdsRequest      - "http://ws.unisoft/FNSNDSCAWS/Request"
  // !:NdsResponse     - "http://ws.unisoft/FNSNDSCAWS/Response"
 
 
  // ************************************************************************ //
  // Namespace : [url]http://ws.unisoft[/url]
  // soapAction: NdsRequest
  // transport : [url]http://schemas.xmlsoap.org/soap/http[/url]
  // binding   : FNSNDSCAWSBinding
  // service   : FNSNDSCAWS
  // port      : FNSNDSCAWS_Port
  // URL       : [url]http://npchk.nalog.ru:80/FNSNDSCAWS[/url]
  // ************************************************************************ //
  FNSNDSCAWS_Port = interface(IInvokable)
  ['{4F17B962-874C-C8B5-315F-940BBF480736}']
    function  NdsRequest(const np_in: NdsRequest): NdsResponse; stdcall;
  end;
 
function GetFNSNDSCAWS_Port(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): FNSNDSCAWS_Port;
 
 
implementation
 
function GetFNSNDSCAWS_Port(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): FNSNDSCAWS_Port;
const
  defWSDL = 'http://npchk.nalog.ru:80/FNSNDSCAWS?wsdl';
  defURL  = 'http://npchk.nalog.ru:80/FNSNDSCAWS';
  defSvc  = 'FNSNDSCAWS';
  defPrt  = 'FNSNDSCAWS_Port';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as FNSNDSCAWS_Port);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;
 
 
initialization
  InvRegistry.RegisterInterface(TypeInfo(FNSNDSCAWS_Port), 'http://ws.unisoft', 'UTF-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(FNSNDSCAWS_Port), 'NdsRequest');
  InvRegistry.RegisterInvokeOptions(TypeInfo(FNSNDSCAWS_Port), ioLiteral);
 
end.
Для функции, отправляющей запрос, тип входного параметра назван NdsRequest, выходного - NdsResponse.
Как я понимаю, мне нужно описать эти типы. Они должны быть наследниками от TRemotable.
Примерно так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
  TNdsRequest = class(TRemotable)
  public
      constructor Create(XMLNode: IXMLNode);
      function ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter:
                            IObjConverter; const Name, URI: InvString; ObjConvOpts:
                            TObjectConvertOptions; out RefID: InvString): IXMLNode; override;
  private
      fXMLNode: IXMLNode;
  end;
 
  TNdsResponse = class(TRemotable);
Реализация конструктора и метода ObjectToSOAP:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
constructor TNdsRequest.Create(XMLNode: IXMLNode);
begin
    fXMLNode := XMLNode;
end;
 
function TNdsRequest.ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter:
                            IObjConverter; const Name, URI: InvString; ObjConvOpts:
                            TObjectConvertOptions; out RefID: InvString): IXMLNode;
begin
    RootNode := fXMLNode.ChildNodes.FindNode('NdsRequest');
    ParentNode := RootNode.ChildNodes.FindNode('NP');
 
    ObjConvOpts := ObjConvOpts + [ocoDontPrefixNode];
 
    Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, 'State', 'http://ws.unisoft', ObjConvOpts, RefID);
end;
Ещё нарыл, что нужно зарегистрировать класс как-то так
Delphi
1
RemClassRegistry.RegisterXSInfo(TypeInfo(TNdsRequest), 'http://ws.unisoft', 'NdsRequest');
Теперь модуль принял такой вид:
Кликните здесь для просмотра всего текста

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : [url]http://npchk.nalog.ru:80/FNSNDSCAWS?wsdl[/url]
// Encoding : UTF-8
// Version  : 1.0
// (06.02.2015 11:31:58 - 1.33.2.5)
// ************************************************************************ //
 
unit FNSNDSCAWS;
 
interface
 
uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns, XMLIntf;
 
type
 
  // ************************************************************************ //
  // The following types, referred to in the WSDL document are not being represented
  // in this file. They are either aliases[@] of other types represented or were referred
  // to but never[!] declared in the document. The types from the latter category
  // typically map to predefined/known XML or Borland types; however, they could also 
  // indicate incorrect WSDL documents that failed to declare or import a schema type.
  // ************************************************************************ //
  // !:NdsRequest      - "http://ws.unisoft/FNSNDSCAWS/Request"
  // !:NdsResponse     - "http://ws.unisoft/FNSNDSCAWS/Response"
 
 
  // ************************************************************************ //
  // Namespace : [url]http://ws.unisoft[/url]
  // soapAction: NdsRequest
  // transport : [url]http://schemas.xmlsoap.org/soap/http[/url]
  // binding   : FNSNDSCAWSBinding
  // service   : FNSNDSCAWS
  // port      : FNSNDSCAWS_Port
  // URL       : [url]http://npchk.nalog.ru:80/FNSNDSCAWS[/url]
  // ************************************************************************ //
 
  TNdsRequest = class(TRemotable)
  public
      constructor Create(XMLNode: IXMLNode);
      function ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter:
                            IObjConverter; const Name, URI: InvString; ObjConvOpts:
                            TObjectConvertOptions; out RefID: InvString): IXMLNode; override;
  private
      fXMLNode: IXMLNode;
  end;
 
  TNdsResponse = class(TRemotable);
 
  FNSNDSCAWS_Port = interface(IInvokable)
  ['{4F17B962-874C-C8B5-315F-940BBF480736}']
    function  NdsRequest(const np_in: TNdsRequest): TNdsResponse; stdcall;
  end;
 
function GetFNSNDSCAWS_Port(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): FNSNDSCAWS_Port;
 
implementation
 
constructor TNdsRequest.Create(XMLNode: IXMLNode);
begin
    fXMLNode := XMLNode;
end;
 
function TNdsRequest.ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter:
                            IObjConverter; const Name, URI: InvString; ObjConvOpts:
                            TObjectConvertOptions; out RefID: InvString): IXMLNode;
begin
    RootNode := fXMLNode.ChildNodes.FindNode('NdsRequest');
    ParentNode := RootNode.ChildNodes.FindNode('NP');
 
    ObjConvOpts := ObjConvOpts + [ocoDontPrefixNode];
 
    Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, 'State', 'http://ws.unisoft', ObjConvOpts, RefID);
end;
 
function GetFNSNDSCAWS_Port(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): FNSNDSCAWS_Port;
const
  defWSDL = 'http://npchk.nalog.ru:80/FNSNDSCAWS?wsdl';
  defURL  = 'http://npchk.nalog.ru:80/FNSNDSCAWS';
  defSvc  = 'FNSNDSCAWS';
  defPrt  = 'FNSNDSCAWS_Port';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as FNSNDSCAWS_Port);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;
 
initialization
  InvRegistry.RegisterInterface(TypeInfo(FNSNDSCAWS_Port), 'http://ws.unisoft', 'UTF-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(FNSNDSCAWS_Port), 'NdsRequest');
  InvRegistry.RegisterInvokeOptions(TypeInfo(FNSNDSCAWS_Port), ioLiteral);
  RemClassRegistry.RegisterXSInfo(TypeInfo(TNdsRequest), 'http://ws.unisoft', 'NdsRequest');
end.

Вызов выполняю так:
Кликните здесь для просмотра всего текста

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SOAPHTTPClient, XMLDoc, XMLIntf;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    MyRio: THTTPRIO;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
uses FNSNDSCAWS;
 
procedure TForm1.Button1Click(Sender: TObject);
var xmlDoc: TXMLDocument;
    Request: IXMLNode;
    NdsRequest: TNdsRequest;
begin
    xmlDoc := TXMLDocument.Create(Application);
    xmlDoc.FileName := 'D:\request.xml';
    xmlDoc.Active := true;
 
    Request := xmlDoc.ChildNodes.FindNode('Data');
 
    myRIO := THTTPRIO.Create(nil);
 
    GetFNSNDSCAWS_Port(true, '', myRIO);
 
    NdsRequest := TNdsRequest.Create(Request);
 
    (myRIO as FNSNDSCAWS_Port).NdsRequest(NdsRequest);
 
    xmlDoc.Free;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    MyRio.Free;
end;
 
end.

Файл request.xml:
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<Data>
<NdsRequest>
<NP INN="525202471833"/>
<NP INN="525202471834"/>
</NdsRequest>
</Data>


В итоге получаю ошибку: Project Wsdl.exe raised exception class ERemotableException with message 'org.xml.sax.SAXParseException; cvc-elt.1.a: Cannot find the declaration of element 'np_in'.'.
Элемент np_in встречается в описании wsdl http://npchk.nalog.ru/FNSNDSCAWS?wsdl.

Помогите мне разобраться что к чему. Что я делаю не так?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.02.2015, 13:19
Ответы с готовыми решениями:

SOAP клиент для web-сервиса
Здравствуйте. Подобно этой теме https://www.cyberforum.ru/delphi-networks/thread1369524.html Сделал подобное приложение на турбо...

WCF клиент для Web-сервиса
Доброе время суток! Пытаюсь создать клиента для Web-сервиса по wsdl. Заголовок и часть аттрибутов в wsdl такие: &lt;!-- ...

SOAP получение данных с web-сервиса
Есть код: &lt;?php $client = new SoapClient(&quot;http://xxx.ru/WCF/ClientService.svc?wsdl&quot;); $params = array ...

4
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
10.02.2015, 02:04
Лучший ответ Сообщение было отмечено Cyberg как решение

Решение

В данном случае SOAP ответ веб-службы не имеет сложной структуры. Поэтому можно вручную обработать вызовы на уровне HTTP протокола. Затем, разобрать XML код SOAP ответа и получить нужные данные. Для работы с HTTP протоколом можно воспользоваться компонентами Indy из палитры Delphi.

Если в SoapUI прослушать HTTP трафик при обращении к службе, увидим следующее:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "POST /FNSNDSCAWS HTTP/1.1[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "Accept-Encoding: gzip,deflate[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "Content-Type: text/xml;charset=UTF-8[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "SOAPAction: "NdsRequest"[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "Content-Length: 398[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "Host: npchk.nalog.ru:80[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "Connection: Keep-Alive[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://ws.unisoft/FNSNDSCAWS/Request">[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "  <soapenv:Header/>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "  <soapenv:Body>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "    <req:NdsRequest>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "      <!--1 to 10000 repetitions:-->[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "      <!-- <req:NP INN="?" KPP="?" DT="?"/> -->[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "      <req:NP INN="525202471833"/>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "      <req:NP INN="525202471834"/>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "    </req:NdsRequest>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "  </soapenv:Body>[\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:>> "</soapenv:Envelope>"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "HTTP/1.1 200 OK[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "Server: nginx/1.6.0[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "Date: Mon, 09 Feb 2015 21:43:10 GMT[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "Content-Type: text/xml;charset=utf-8[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "Content-Length: 315[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "Connection: keep-alive[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "[\r][\n]"
Tue Feb 10 02:43:14 GST 2015:DEBUG:<< "<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><NdsResponse xmlns="http://ws.unisoft/FNSNDSCAWS/Response" DTActFL="09.02.2015" DTActUL="09.02.2015"><NP INN="525202471833" State="2"/><NP INN="525202471834" State="4"/></NdsResponse></S:Body></S:Envelope>"
Здесь видно, какие HTTP заголовки используются при взаимодействии. Такие же заголовки будем формировать в коде на Delphi.

Такое взаимодействие можно организовать следующим образом.
На форму надо положить:
Delphi
1
2
3
4
5
    IdHTTP1: TIdHTTP;
    XMLDocument1: TXMLDocument;
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
Для кнопки Button1 создать обработчик события OnClick. В Memo1 вводится XML код SOAP запроса:
Memo1.Text:
Code
1
2
3
4
5
6
7
8
9
10
11
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://ws.unisoft/FNSNDSCAWS/Request">
  <soapenv:Header/>
  <soapenv:Body>
    <req:NdsRequest>
      <!--1 to 10000 repetitions:-->
      <!-- <req:NP INN="?" KPP="?" DT="?"/> -->
      <req:NP INN="525202471833"/>
      <req:NP INN="525202471834"/>
    </req:NdsRequest>
  </soapenv:Body>
</soapenv:Envelope>
В Memo2 выводятся результаты обработки ответа веб-службы.
Код модуля:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, xmldom, XMLIntf, msxmldom, XMLDoc;
 
type
  TForm1 = class(TForm)
    IdHTTP1: TIdHTTP;
    XMLDocument1: TXMLDocument;
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  //Переменные, используемые в коде взаимодействия с веб-службой.
  SUtf8 : UTF8String; //type UTF8String = AnsiString.
  MsReq, MsResp, Ms : TMemoryStream; //Байтовые потоки с данными SOAP запроса и SOAP ответа.
 
  //Переменные, используемые при анализе XML данных SOAP ответа веб-службы.
  S : String;
  i, j : Integer;
  INode, IAttr : IXMLNode;
  IList : IXMLNodeList;
begin
  //----------------------------------------
  //1. Подготовка.
  //----------------------------------------
 
  //Очистка и инициализация.
  IdHTTP1.Request.Clear;
  IdHTTP1.Response.Clear;
  Ms     := nil;
  MsReq  := nil;
  MsResp := nil;
  Memo2.Clear;
 
  try
    //Содержание SOAP запроса берём из Memo1.
    S := Trim(Memo1.Text);
    {
    Memo1.Text:
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://ws.unisoft/FNSNDSCAWS/Request">
      <soapenv:Header/>
      <soapenv:Body>
        <req:NdsRequest>
          <!--1 to 10000 repetitions:-->
          <!-- <req:NP INN="?" KPP="?" DT="?"/> -->
          <req:NP INN="525202471833"/>
          <req:NP INN="525202471834"/>
        </req:NdsRequest>
      </soapenv:Body>
    </soapenv:Envelope>
    }
    //Перекодируем текст в UTF-8 кодировку.
    SUtf8 := Utf8Encode(S);
    //Запись SOAP запроса в байтовый поток.
    MsReq := TMemoryStream.Create;
    MsReq.Write(SUtf8[1], Length(SUtf8));
 
    //Формируем заголовок HTTP запроса.
    IdHTTP1.ProtocolVersion := pv1_1;
    IdHTTP1.Request.CustomHeaders.Add('Accept-Encoding: gzip,deflate');
    IdHTTP1.Request.ContentType := 'text/xml;charset=UTF-8';
    IdHTTP1.Request.CustomHeaders.Add('SOAPAction: "NdsRequest"');
    IdHTTP1.Request.Connection := 'Keep-Alive';
    IdHTTP1.Request.ProcessHeaders;
 
    //Создаём байтовый поток для записи ответа веб-службы.
    MsResp := TMemoryStream.Create;
 
    //----------------------------------------
    //2. Взаимодействие с веб-службой.
    //----------------------------------------
 
    //Посылаем запрос веб-службе и получаем от неё ответ.
    MsReq.Position := 0; //Потоковый указатель устанавливаем на начало потока.
    IdHTTP1.Post('http://npchk.nalog.ru:80/FNSNDSCAWS', MsReq, MsResp);
 
    //----------------------------------------
    //3. Анализ ответа веб-службы.
    //----------------------------------------
 
    {Печатаем в Memo XML код SOAP ответа. Для этого сначала данные потока-ответа
    переписываем в строку UTF-8, а затем выполняем преобразование текста в ANSI
    или UNICODE кодировку в зависимости от версии Delphi.}
    //Запись данных ответа в строку UTF-8.
    SetLength(SUtf8, MsResp.Size);
    MsResp.Position := 0; //Потоковый указатель устанавливаем на начало потока.
    MsResp.Read(SUtf8[1], Length(SUtf8));
    //Перекодируем текст в ANSI или UNICODE кодировку, в зависимости от версии Delphi.
    S := Utf8Decode(SUtf8);
    //Форматируем полученный XML код и показываем его в Memo.
    Memo2.Lines.Add('----------');
    Memo2.Lines.Add('Ответ веб-службы:');
    Memo2.Lines.Add( Trim(FormatXMLData(S)) );
 
    //Теперь анализируем ответ веб-службы. Для этого можно воспользоваться экземпляром
    //TXMLDocument. Или можно с помощью действий со стоками извлечь нужные данные.
 
    //Обработка с помощью экземпляра TXMLDocument.
 
    //Загружаем XML данные в XML документ.
    MsResp.Position := 0;
    XMLDocument1.LoadFromStream(MsResp, xetUTF_8);
    {Настраиваем XML документ.
    -[doNodeAutoCreate] - запрет на автоматическое создание узлов при попытке чтения.
    -[doAutoSave] - запрет на автоматическое сохранение изменений при закрытии документа.}
    XMLDocument1.Options := XMLDocument1.Options - [doNodeAutoCreate, doAutoSave];
    XMLDocument1.Active := True; //Включаем разбор DOM модели.
 
    //Извлекаем из XML сведения о контрагентах и распечатываем их в Memo2.
    Memo2.Lines.Add('----------');
    Memo2.Lines.Add('Сведения о контрагентах:');
    //Элемент документа <S:Envelope>.
    INode := XMLDocument1.DocumentElement;
    //Первый вложенный элемент <S:Body>.
    INode := INode.ChildNodes.FindNode('S:Body');
    {Далее, в следствии какого-то бага, наверное, по вызову FindNode('NdsResponse')
    элемент <NdsResponse> не обнаруживается. :-) В связи с этим пришлось
    действовать через вызов Get(). Будем считать, что для <S:Body> первым
    вложенным элементом является элемент <NdsResponse>.}
    //Получаем список элементов, которые вложены в <NdsResponse> .
    IList := INode.ChildNodes.Get(0).ChildNodes;
    Memo2.Lines.Add('Количество элементов: ' + IntToStr(IList.Count));
    for i := 0 to IList.Count - 1 do //Перебор элементов списка.
    begin
      INode := IList.Get(i); //Очередной элемент.
      S := '<' + INode.NodeName + '>: ';
      for j := 0 to INode.AttributeNodes.Count - 1 do //Перебор атрибутов.
      begin
        IAttr := INode.AttributeNodes.Get(j); //Очередной атрибут.
        if j > 0 then
          S := S + '; ';
        S := S + IAttr.NodeName + '="' + IAttr.NodeValue + '"';
      end;
      Memo2.Lines.Add(S);
    end;
  finally
    FreeAndNil(Ms);
    FreeAndNil(MsReq);
    FreeAndNil(MsResp);
  end;
end;
 
end.
Миниатюры
SOAP клиент для web-сервиса npchk.nalog.ru  
Вложения
Тип файла: 7z WebService-FNSNDSCAWS-01.7z (228.7 Кб, 262 просмотров)
1
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 2
10.02.2015, 11:14  [ТС]
Спасибо. Всё замечательно работает. По началу не рассматривал возможность работы через Indy. Однажды только делал на нём отправку/приём почты.
0
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
10.02.2015, 11:20
Да - иногда проще через Indy сделать, чем возиться с импортом WSDL и прочими этапами. В моём предыдущем посте, в коде - там лишняя переменная потока Ms - надо убрать её.
0
0 / 0 / 0
Регистрация: 31.03.2016
Сообщений: 2
31.03.2016, 14:19
Дорогие друзья, я решаю подобную задачу в Turbo Delphi
и он подчеркивает красным строку "IdHTTP1.Request.ProcessHeaders;"
с сообщением 'IdHTTP1Request' does not contain member named 'ProcessHeaders'

при этом вылетает ошибка на строке "MsResp.Read(SUtf8[1], Length(SUtf8));"
с сообщением "XML document must have a top level element line:0"

помогите,пожалуйста. скажите, как быть?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.03.2016, 14:19
Помогаю со студенческими работами здесь

Отображение xml из SOAP web-сервиса
Добрый день! Подскажите есть web-сервис, написанный по технологии SOAP, необходимо создать php файл, который будет отображать...

Выбор средств разработки для web-сервиса
Приветствую всех! Не знал где задать свой вопрос, решил тут) я web-программированием практически не занимался, чуть-чуть в рамках одного из...

Как задать параметр для web-сервиса?
Имеется web-сервис (не WCF!) service.svc. Аяксом посылаю к нему post-запрос. Получаю ошибку: Вопрос: как увеличить эту квоту для...

Что лучше выбрать для создания Web сервиса?
WCF или Core Web API?

Нужен web программист для реализация проекта сервиса грузоперевозок
Необходимо реализовать проект на подобие http://perevezi.ru/ или http://www.vezetvsem.info/ Желательно прикрепить скрипт работы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru