Как парсить XML SOAP в MS SQL
В отличие от более простого MySQL, у MS SQL даже в Express версии есть достаточно реальная поддержка XML. В PostgreSQL такая поддержка в принципе тоже есть, но в виде отдельных пакетов.
С помощью XML-поддержки можно сделать много полезного в MS SQL - многое но не все! В самый нужный момент микрософтовцы как всегда затупили. Билл Гейтс даже принял на работу к себе 700 копрофилов и зоофилов в надежде, что интеллектуальный потенциал микрософта хоть чуть-чуть увеличится, но увы, даже они не додумались подсказать главного - по стандарту XML идентификаторы могут иметь минус внутри идентификатора неймспейса схемы. Впрочем, мы все знаем, что ни билогейтсовские копрофилы, ни зоофилы, ни все остальные микрософтовцы интернет-стандартов никогда не читали.
Итак, что же все-таки возможно сделать с помощью встроенной в MS SQL поддержки XML?
C помощью встроенной в MS SQL поддержки XPATH-выражений можно довольно удобно распарсить простейшие XML :
1: ALTER View [dbo].[GetOperator]
2: as
3: select ID,GroupID,CyberID,SourceOrder,
4: Node.value('/operator[1]/name[1]', 'nvarchar(256)') as [name],
5: Node.value('/operator[1]/name_for_cheque[1]', 'nvarchar(256)') as [name_for_cheque],
6: Node.value('/operator[1]/inn_for_cheque[1]', 'nvarchar(256)')as [inn_for_cheque],
7: Node.value('/operator[1]/comission[1]/@amount', 'int')as [comission],
8: Node.value('/operator[1]/limit[1]/@min', 'int')as [min],
9: Node.value('/operator[1]/limit[1]/@max', 'int')as [max],
10: Node.value('/operator[1]/image[1]', 'nvarchar(256)')as [image],
11: Node.value('/operator[1]/rootmenuimage[1]', 'nvarchar(256)')as [rootmenuimage],
12: Node.query('/operator/fields')as [fields],
13: Node.query('/operator/processor')as [processor]
14: from dbo.MobileOperator
![]() |
![]() |
Однако, на практике, увы, как правило возникают гораздо более сложные задачи. Как бы для них предусмотрена конструкция WITH NAMESPACE, однако она не поддерживает совершенно обычные стандартные идентификаторы схем. Да и выгребать вручную идентификаторы замучаешься. А если схема то одна, то другая? Как динамически менять схемы в уродской конструкции WITH NAMESPACE?
Здесь на помощь придут только SQL CLR сборки, о которых много сказано на моем сайте Однако, делать полностью универсальную сборку - которой бы могли воспользоваться все, я не вижу смысла. У нее будет слишком гиморойный синтаксис вызова. Я вижу смысл только автоматизировать выгребание неймспейсов, а собственно вписывание XPATH выражений оставить на откуп пользователю.
Таким образом, ниже я покажу сборку, которая распарсит стандартный SOAP и вернет вместо XML просто табличку:
![]() |
![]() |
Обратите внимание, что это как раз противоположная операция преобразования от другой распространенной операции, многократно описанной на моем сайте - Этюды на ASP2. Делаем RSS-канал на одной SQL-процедуре - когда требуется реляционные данные преобразовать в XML (тоже на уровне SQL).
Итак, вот долгожданное чудо - код SQL CLR сборки с табличным возвратом (на примере парсинга SOAP-ответа платежного сервиса Assist):
1: Imports System
2: Imports System.Data
3: Imports System.Data.SqlClient
4: Imports System.Data.SqlTypes
5: Imports Microsoft.SqlServer.Server
6:
7: Friend Class OneRow
8: Public i As Integer
9: Public ordernumber As String
10: Public response_code As String
11: Public recommendation As String
12: Public message As String
13: Public comment As String
14: Public [date] As String
15: Public total As String
16: Public currency As String
17: Public cardtype As String
18: Public cardnumber As String
19: Public lastname As String
20: Public firstname As String
21: Public middlename As String
22: Public address As String
23: Public email As String
24: Public country As String
25: Public rate As String
26: Public approvalcode As String
27: Public cardsubtype As String
28: Public cvc2 As String
29: Public cardholder As String
30: Public ipaddress As String
31: Public protocoltypename As String
32: Public billnumber As String
33: Public bankname As String
34: Public status As String
35: Public error_code As String
36: Public error_comment As String
37: Public packetdate As String
38: Public processingname As String
39: Public paymenttransactiontype_id As String
40: Public faultcode As String
41: Public faultstring As String
42:
43: Public Sub New(ByVal DR As SqlDataReader)
44: Try
45: i = CInt(DR(0))
46: '
47: 'Распарсили ответ
48: If IsDBNull(DR(1)) Then
49: Exit Sub
50: ElseIf DR(1).ToString.Contains("faultcode") Then
51: 'сообщение об ошибке авторизации
52: Dim NameSpaceParcer2 As New ParceNamespace(DR(1).ToString)
53: Dim _FaultCode As System.Xml.XmlNode = NameSpaceParcer2.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/SOAP-ENV:Fault/faultcode", NameSpaceParcer2.NamespaceManager)
54: Dim _FaultString As System.Xml.XmlNode = NameSpaceParcer2.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/SOAP-ENV:Fault/faultstring", NameSpaceParcer2.NamespaceManager)
55: '
56: faultcode = _FaultCode.InnerText
57: faultstring = _FaultString.InnerText
58: '
59: ElseIf DR(1).ToString.Contains("<ASS-NS:GetPaymentsResultResponse") Then
60: 'нормальный ответ
61: Dim NameSpaceParcer As New ParceNamespace(DR(1).ToString)
62: Dim _Ordernumber As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/ordernumber", NameSpaceParcer.NamespaceManager)
63: Dim _Response_code As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/response_code", NameSpaceParcer.NamespaceManager)
64: Dim _Recommendation As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/recommendation", NameSpaceParcer.NamespaceManager)
65: Dim _Message As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/message", NameSpaceParcer.NamespaceManager)
66: Dim _Comment As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/comment", NameSpaceParcer.NamespaceManager)
67: Dim _Date As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/date", NameSpaceParcer.NamespaceManager)
68: Dim _Total As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/total", NameSpaceParcer.NamespaceManager)
69: Dim _Currency As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/currency", NameSpaceParcer.NamespaceManager)
70: Dim _Cardtype As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/cardtype", NameSpaceParcer.NamespaceManager)
71: Dim _Cardnumber As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/cardnumber", NameSpaceParcer.NamespaceManager)
72: Dim _Lastname As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/lastname", NameSpaceParcer.NamespaceManager)
73: Dim _Firstname As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/firstname", NameSpaceParcer.NamespaceManager)
74: Dim _Middlename As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/middlename", NameSpaceParcer.NamespaceManager)
75: Dim _Address As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/address", NameSpaceParcer.NamespaceManager)
76: Dim _Email As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/email", NameSpaceParcer.NamespaceManager)
77: Dim _Country As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/country", NameSpaceParcer.NamespaceManager)
78: Dim _Rate As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/rate", NameSpaceParcer.NamespaceManager)
79: Dim _Approvalcode As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/approvalcode", NameSpaceParcer.NamespaceManager)
80: Dim _Cardsubtype As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/cardsubtype", NameSpaceParcer.NamespaceManager)
81: Dim _Cvc2 As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/cvc2", NameSpaceParcer.NamespaceManager)
82: Dim _Cardholder As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/cardholder", NameSpaceParcer.NamespaceManager)
83: Dim _Ipaddress As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/ipaddress", NameSpaceParcer.NamespaceManager)
84: Dim _Protocoltypename As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/protocoltypename", NameSpaceParcer.NamespaceManager)
85: Dim _Billnumber As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/billnumber", NameSpaceParcer.NamespaceManager)
86: Dim _Bankname As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/bankname", NameSpaceParcer.NamespaceManager)
87: Dim _Status As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/status", NameSpaceParcer.NamespaceManager)
88: Dim _Error_code As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/error_code", NameSpaceParcer.NamespaceManager)
89: Dim _Error_comment As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/error_comment", NameSpaceParcer.NamespaceManager)
90: Dim _Packetdate As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/packetdate", NameSpaceParcer.NamespaceManager)
91: Dim _Processingname As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/processingname", NameSpaceParcer.NamespaceManager)
92: Dim _Paymenttransactiontype_id As System.Xml.XmlNode = NameSpaceParcer.XML.SelectSingleNode("/SOAP-ENV:Envelope/SOAP-ENV:Body/ASS-NS:GetPaymentsResultResponse/return/payment/paymenttransactiontype_id", NameSpaceParcer.NamespaceManager)
93: '
94: ordernumber = _Ordernumber.InnerText
95: response_code = _Response_code.InnerText
96: recommendation = _Recommendation.InnerText
97: message = _Message.InnerText
98: comment = _Comment.InnerText
99: [date] = _Date.InnerText
100: total = _Total.InnerText
101: currency = _Currency.InnerText
102: cardtype = _Cardtype.InnerText
103: cardnumber = _Cardnumber.InnerText
104: lastname = _Lastname.InnerText
105: firstname = _Firstname.InnerText
106: middlename = _Middlename.InnerText
107: address = _Address.InnerText
108: email = _Email.InnerText
109: country = _Country.InnerText
110: rate = _Rate.InnerText
111: approvalcode = _Approvalcode.InnerText
112: cardsubtype = _Cardsubtype.InnerText
113: cvc2 = _Cvc2.InnerText
114: cardholder = _Cardholder.InnerText
115: ipaddress = _Ipaddress.InnerText
116: protocoltypename = _Protocoltypename.InnerText
117: billnumber = _Billnumber.InnerText
118: bankname = _Bankname.InnerText
119: status = _Status.InnerText
120: error_code = _Error_code.InnerText
121: error_comment = _Error_comment.InnerText
122: packetdate = _Packetdate.InnerText
123: processingname = _Processingname.InnerText
124: paymenttransactiontype_id = _Paymenttransactiontype_id.InnerText
125: Else
126: faultcode = "AssistResponse Parser error"
127: faultstring = DR(1).ToString
128: End If
129: Catch ex As Exception
130: faultcode = "AssistResponse Parser error"
131: faultstring = ex.Message
132: End Try
133: End Sub
134: End Class
135:
136:
137: Partial Public Class UserDefinedFunctions
138: <Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName:="FillOneRow", Name:="AssistResponse", _
139: TableDefinition:="i int, " & _
140: "ordernumber Nvarchar(max), " & _
141: "response_code Nvarchar(max), " & _
142: "recommendation Nvarchar(max), " & _
143: "message Nvarchar(max), " & _
144: "comment Nvarchar(max), " & _
145: "date Nvarchar(max), " & _
146: "total Nvarchar(max), " & _
147: "currency Nvarchar(max), " & _
148: "cardtype Nvarchar(max), " & _
149: "cardnumber Nvarchar(max), " & _
150: "lastname Nvarchar(max), " & _
151: "firstname Nvarchar(max), " & _
152: "middlename Nvarchar(max), " & _
153: "address Nvarchar(max), " & _
154: "email Nvarchar(max), " & _
155: "country Nvarchar(max), " & _
156: "rate Nvarchar(max), " & _
157: "approvalcode Nvarchar(max), " & _
158: "cardsubtype Nvarchar(max), " & _
159: "cvc2 Nvarchar(max), " & _
160: "cardholder Nvarchar(max), " & _
161: "ipaddress Nvarchar(max), " & _
162: "protocoltypename Nvarchar(max), " & _
163: "billnumber Nvarchar(max), " & _
164: "bankname Nvarchar(max), " & _
165: "status Nvarchar(max), " & _
166: "error_code Nvarchar(max), " & _
167: "error_comment Nvarchar(max), " & _
168: "packetdate Nvarchar(max), " & _
169: "processingname Nvarchar(max), " & _
170: "paymenttransactiontype_id Nvarchar(max), " & _
171: "faultcode Nvarchar(max), " & _
172: "faultstring Nvarchar(max)", DataAccess:=DataAccessKind.Read)> _
173: Public Shared Function AssistResponse() As IEnumerable
174: Dim X As New Collections.Generic.List(Of OneRow)
175: Using CN As New SqlConnection("context connection=true")
176: Using CMD As SqlCommand = CN.CreateCommand()
177: CMD.CommandText = "select i,AssistStatusResponseXML from dbo.Request with (nolock)"
178: CN.Open()
179: Using DR = CMD.ExecuteReader
180: While DR.Read
181: X.Add(New OneRow(DR))
182: End While
183: DR.Close()
184: End Using
185: End Using
186: CN.Close()
187: End Using
188: Return X
189: End Function
190:
191: Public Shared Sub FillOneRow(ByVal row As Object, _
192: <Runtime.InteropServices.Out()> ByRef i As Integer, _
193: <Runtime.InteropServices.Out()> ByRef ordernumber As String, _
194: <Runtime.InteropServices.Out()> ByRef response_code As String, _
195: <Runtime.InteropServices.Out()> ByRef recommendation As String, _
196: <Runtime.InteropServices.Out()> ByRef message As String, _
197: <Runtime.InteropServices.Out()> ByRef comment As String, _
198: <Runtime.InteropServices.Out()> ByRef [date] As String, _
199: <Runtime.InteropServices.Out()> ByRef total As String, _
200: <Runtime.InteropServices.Out()> ByRef currency As String, _
201: <Runtime.InteropServices.Out()> ByRef cardtype As String, _
202: <Runtime.InteropServices.Out()> ByRef cardnumber As String, _
203: <Runtime.InteropServices.Out()> ByRef lastname As String, _
204: <Runtime.InteropServices.Out()> ByRef firstname As String, _
205: <Runtime.InteropServices.Out()> ByRef middlename As String, _
206: <Runtime.InteropServices.Out()> ByRef address As String, _
207: <Runtime.InteropServices.Out()> ByRef email As String, _
208: <Runtime.InteropServices.Out()> ByRef country As String, _
209: <Runtime.InteropServices.Out()> ByRef rate As String, _
210: <Runtime.InteropServices.Out()> ByRef approvalcode As String, _
211: <Runtime.InteropServices.Out()> ByRef cardsubtype As String, _
212: <Runtime.InteropServices.Out()> ByRef cvc2 As String, _
213: <Runtime.InteropServices.Out()> ByRef cardholder As String, _
214: <Runtime.InteropServices.Out()> ByRef ipaddress As String, _
215: <Runtime.InteropServices.Out()> ByRef protocoltypename As String, _
216: <Runtime.InteropServices.Out()> ByRef billnumber As String, _
217: <Runtime.InteropServices.Out()> ByRef bankname As String, _
218: <Runtime.InteropServices.Out()> ByRef status As String, _
219: <Runtime.InteropServices.Out()> ByRef error_code As String, _
220: <Runtime.InteropServices.Out()> ByRef error_comment As String, _
221: <Runtime.InteropServices.Out()> ByRef packetdate As String, _
222: <Runtime.InteropServices.Out()> ByRef processingname As String, _
223: <Runtime.InteropServices.Out()> ByRef paymenttransactiontype_id As String, _
224: <Runtime.InteropServices.Out()> ByRef faultcode As String, _
225: <Runtime.InteropServices.Out()> ByRef faultstring As String)
226: '
227: If row Is Nothing Then Exit Sub
228: '
229: Dim X As OneRow = CType(row, OneRow)
230: '
231: i = X.i
232: ordernumber = X.ordernumber
233: response_code = X.response_code
234: recommendation = X.recommendation
235: message = X.message
236: comment = X.comment
237: [date] = X.[date]
238: total = X.total
239: currency = X.currency
240: cardtype = X.cardtype
241: cardnumber = X.cardnumber
242: lastname = X.lastname
243: firstname = X.firstname
244: middlename = X.middlename
245: address = X.address
246: email = X.email
247: country = X.country
248: rate = X.rate
249: approvalcode = X.approvalcode
250: cardsubtype = X.cardsubtype
251: cvc2 = X.cvc2
252: cardholder = X.cardholder
253: ipaddress = X.ipaddress
254: protocoltypename = X.protocoltypename
255: billnumber = X.billnumber
256: bankname = X.bankname
257: status = X.status
258: error_code = X.error_code
259: error_comment = X.error_comment
260: packetdate = X.packetdate
261: processingname = X.processingname
262: paymenttransactiontype_id = X.paymenttransactiontype_id
263: faultcode = X.faultcode
264: faultstring = X.faultstring
265: End Sub
266: End Class
267:
268:
269: Public Class ParceNamespace
270:
271: Dim _XML As New System.Xml.XmlDocument
272: Public ReadOnly Property XML() As System.Xml.XmlDocument
273: Get
274: Return _XML
275: End Get
276: End Property
277:
278: Dim _NamespaceManager As System.Xml.XmlNamespaceManager
279: Public ReadOnly Property NamespaceManager() As System.Xml.XmlNamespaceManager
280: Get
281: Return _NamespaceManager
282: End Get
283: End Property
284:
285:
286: Public Sub New(ByVal ResponseXML As String)
287: _XML.LoadXml(ResponseXML)
288: Dim AllNameSpace As New System.Collections.Specialized.NameValueCollection
289: For I As Integer = 1 To 20
290: Dim XpatchBuilder As New System.Text.StringBuilder
291: XpatchBuilder.Append("/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*", 0, I * 2)
292: Dim CurrentNodeList As System.Xml.XmlNodeList = _XML.SelectNodes(XpatchBuilder.ToString)
293: If CurrentNodeList IsNot Nothing Then
294: If CurrentNodeList.Count > 0 Then
295: For Each CurrentNode As System.Xml.XmlNode In CurrentNodeList
296: If CurrentNode.Attributes IsNot Nothing Then
297: If CurrentNode.Attributes.Count > 0 Then
298: For Each CurrentAttr As System.Xml.XmlAttribute In CurrentNode.Attributes
299: If CurrentAttr.Prefix = "xmlns" Then
300: AllNameSpace.Add(CurrentAttr.LocalName, CurrentAttr.Value)
301: End If
302: Next
303: End If
304: End If
305: Next
306: Else
307: Exit For
308: End If
309: End If
310: Next
311: For i As Integer = 0 To AllNameSpace.Count - 1
312: _XML.NameTable.Add(AllNameSpace.Keys(i))
313: Next
314: _NamespaceManager = New System.Xml.XmlNamespaceManager(_XML.NameTable)
315: For i As Integer = 0 To AllNameSpace.Count - 1
316: _NamespaceManager.AddNamespace(AllNameSpace.Keys(i), AllNameSpace.Get(i))
317: Next
318: End Sub
319:
320: End Class
Как видите, табличная сборка вполне тривиальна. Функция AssistResponse (137-189) читает из базы XML, декларирует формат выходной таблички и обьявляет что имя функции, заполняющей каждую строку таблички - FillOneRow.
Класс OneRow (7-134) готовит данные для одной строки нашей таблички, которая должна получиться в итоге вызова сборки. А сама функция FillOneRow (191-266) в нашем случае получается тупо заглушкой, которая копирует данные из класса OneRow в созданную в строке 181 каждую новую строку таблички.
Небольшая хитрость, до которой так и не сумели додуматься в гавнософте - это сбор и автоматическое добавление всех существующих в SOAP неймспейсов. Это я делаю в строках 269-320. И непосредственно перед вызовом XPATH-выражений, с помощью которых я выковыриваю из XML данные (53-54,62-92) я автоматически собираю неймспейсы по XML cвоим сервисом. В итоге я могу тупо копировать XPATH например из Альтовы, не заморачиваясь каждый раз - а какой же мне сейчас нужен NamespaceManager для этого отбора?
Ну вот собственно и все. Надеюсь после этой моей публикации ни задачка парсинга SOAP внутри MS SQL, ни задача коллекционирования Namespace по XML уже ни у кого проблем вызывать не будет.
![](http://forum.vb-net.com/GetTopicCount.png?id=9DEACCC3-9EE6-4DB2-85D3-1627A90CA6F1)
<SITEMAP> <MVC> <ASP> <NET> <DATA> <KIOSK> <FLEX> <SQL> <NOTES> <LINUX> <MONO> <FREEWARE> <DOCS> <ENG> <CHAT ME> <ABOUT ME> < THANKS ME> |