Страницы: 1
RSS
Парсинг кода с web-сервиса
 
Добрый день!

Прошу подсказать...
Что делаю:
1. Есть веб-сервис 1С. На него посылаю запрос и получаю ответ через SOAP запрос.
2. Текст ответа падает в переменную "Ответ".
3. Делаю парсинг "подручными" методами.

Внутри ответа веб-сервиса идут блоки: <m:НеподписанныйДокумент> информация </m:НеподписанныйДокумент>
*1234 - это какая то информация номера документов и т.д.

Проблема в том, что таких блоков (<m:НеподписанныйДокумент> информация </m:НеподписанныйДокумент>) может быть 50 шт. и более.
Мне же нужна информация из этих блоков (сумма, номера, УИД и т.д).

Сейчас забираю данные кустарным способом. Высчитываю шапку и тд. - работает честно говоря не стабильно.

Вопрос, как парсить нормально такие вещи?)
Код
лево = InStr(Ответ, "<m:НеподписанныйДокумент>") + 25
право = InStr(лево, Ответ, "</m:НеподписанныйДокумент>")
середина = право - лево
ОКВЭД = Mid(Ответ, лево, середина)
Код
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Body>
      <m:getUPDListResponse xmlns:m="itPersona">
         <m:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <m:НеподписанныйДокумент>
               <m:Номер>1234 </m:Номер>
               <m:Дата>2020-09-05</m:Дата>
               <m:Сумма>50.7</m:Сумма>
               <m:УИД>1234</m:УИД>
               <m:ИдентификторЭДО>1234</m:ИдентификторЭДО>
               <m:ОбменЭДО>false</m:ОбменЭДО>
               <m:Статус>Отправлен по почте</m:Статус>
               <m:ДатаСтатуса>2020-09-30T10:48:14</m:ДатаСтатуса>
           </m:НеподписанныйДокумент>
         </m:return>
      </m:getUPDListResponse>
   </soap:Body>
</soap:Envelope>
Изменено: Павел Баскаков - 27.10.2022 10:41:56
Всё что мы есть - это результат наших мыслей ©Будда
 
ещё более колхоз:
Код
Sub qwert()
    Dim s
    s = "<soap:Envelope xmlns:soap=""""http://www.w3.org/2003/05/soap-envelope"""">"
    s = s & vbCrLf & "<soap:Body>"
    s = s & vbCrLf & "<m:getUPDListResponse xmlns:m=""""itPersona"""">"
    s = s & vbCrLf & "<m:return xmlns:xs=""""http://www.w3.org/2001/XMLSchema"""" xmlns:xsi=""""http://www.w3.org/2001/XMLSchema-instance"""">"
    s = s & vbCrLf & "<m:НеподписанныйДокумент>"
    s = s & vbCrLf & "<m:Номер>1234 </m:Номер>"
    s = s & vbCrLf & "<m:Дата>2020-09-05</m:Дата>"
    s = s & vbCrLf & "<m:Сумма>50.7</m:Сумма>"
    s = s & vbCrLf & "<m:УИД>1234</m:УИД>"
    s = s & vbCrLf & "<m:ИдентификторЭДО>1234</m:ИдентификторЭДО>"
    s = s & vbCrLf & "<m:ОбменЭДО>false</m:ОбменЭДО>"
    s = s & vbCrLf & "<m:Статус>Отправлен по почте</m:Статус>"
    s = s & vbCrLf & "<m:ДатаСтатуса>2020-09-30T10:48:14</m:ДатаСтатуса>"
    s = s & vbCrLf & "</m:НеподписанныйДокумент>"
    s = s & vbCrLf & "</m:return>"
    s = s & vbCrLf & "</m:getUPDListResponse>"
    s = s & vbCrLf & "</soap:Body>"
    s = s & vbCrLf & "</soap:Envelope>"
'    Debug.Print s
    
    Debug.Print "Номер", get_dan(s, "Номер")
    Debug.Print "Сумма", get_dan(s, "Сумма")
    Debug.Print "УИД", get_dan(s, "УИД")
    
    
End Sub

Function get_dan(s, kl)
    If InStr(1, s, kl) > 0 Then
        get_dan = Split(Split(s, kl & ">")(1), "<")(0)
    End If
End Function
большая часть кода формирование списка
в дебаггере
Номер         1234
Сумма         50.7
УИД           1234

или в цикле
Код
    a = Split("Номер,Сумма,УИД", ",")
    For i = 0 To UBound(a)
        Debug.Print a(i), get_dan(s, a(i))
    Next i
Изменено: Александр Моторин - 27.10.2022 11:19:04
 
Не совсем понятно, как выглядит xml с двумя и более документами, но если так:
Код
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Body>
      <m:getUPDListResponse xmlns:m="itPersona">
         <m:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <m:НеподписанныйДокумент>
               <m:Номер>1234 </m:Номер>
               <m:Дата>2020-09-05</m:Дата>
               <m:Сумма>50.7</m:Сумма>
           </m:НеподписанныйДокумент>
           <m:НеподписанныйДокумент>
               <m:Номер>5678 </m:Номер>
               <m:Дата>2020-09-06</m:Дата>
               <m:Сумма>60.7</m:Сумма>
           </m:НеподписанныйДокумент>
         </m:return>
      </m:getUPDListResponse>
   </soap:Body>
</soap:Envelope>

То код может быть такой:

Код
    'Reference: Microsoft XML, v3.0
    Dim xml As New MSXML2.DOMDocument, elem As MSXML2.IXMLDOMElement
    
    xml.async = False 'отключаем асинхонный запрос, иначе данные не успевают загрузиться
    xml.LoadXML (Ответ)  'загружаем ответ xml
    For Each elem In xml.DocumentElement.SelectNodes("//soap:Body/m:getUPDListResponse/m:return/m:НеподписанныйДокумент")
        Debug.Print elem.SelectSingleNode("m:Номер").Text
    Next elem
Изменено: webley - 27.10.2022 11:17:12
 
если блоков <m:НеподписанныйДокумент много, то сначала разбить текст Split по "<m:НеподписанныйДокумент"
и потом в цикле обработать все элементы начиная с первого  
 
webley, Очень интересно.
Однако при тесте возник конфликт с Microsoft XML, v3.0.
Так как уже используется в запросе Microsoft XML, v6.0.
И то и то выбрать не даёт.

Попробовал прописать MSXML2.DOMDocument60 - не ругается, но похоже чего то не хватает, так как выдаёт на строке:
For Each elem In xml.DocumentElement.SelectNodes("//soap:Body/m:getUPDListResponse/m:return/m:НеподписанныйДокумент")


Код
Sub h()

    Dim xml As New MSXML2.DOMDocument60, elem As MSXML2.IXMLDOMElement
     
    xml.async = False 'отключаем асинхонный запрос, иначе данные не успевают загрузиться
    xml.LoadXML (ответ)  'загружаем ответ xml
    For Each elem In xml.DocumentElement.SelectNodes("//soap:Body/m:getUPDListResponse/m:return/m:НеподписанныйДокумент")
        Debug.Print elem.SelectSingleNode("m:Номер").Text
    Next elem
End Sub
Изменено: Павел Баскаков - 27.10.2022 11:37:24
Всё что мы есть - это результат наших мыслей ©Будда
 
То есть структура сейчас такая (затёр некоторые данные входа ибо закрытый ресурс)

Ещё думаю что должно быть с soap:Envelope:
Код
For Each elem In xml.DocumentElement.SelectNodes("//soap:Envelope/soap:Body/m:getUPDListResponse/m:return/m:НеподписанныйДокумент")
Но пока не помогло.


Полный код:
Код
Public ответ As Variant
Sub ntcn()


инн = Sheets("упд").Range("b1")
 
 'Set and instantiate our working objects
    Dim Req As Object
    Dim sEnv As String
    Dim Resp As New MSXML2.DOMDocument60
    Set Req = CreateObject("MSXML2.XMLHTTP")
    Set Resp = CreateObject("MSXML2.DOMDocument.6.0")
    Req.Open "Post", "ссылка на веб сервис 1С", False
    
 ' we create our SOAP envelope for submission to the Web Service
     sEnv = sEnv & "  <soapenv:Envelope "
     sEnv = sEnv & "  xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"""
     sEnv = sEnv & "  xmlns:itp=""rrrr"">"
     sEnv = sEnv & "  <soapenv:Header/>"
     sEnv = sEnv & "  <soapenv:Body>"
     sEnv = sEnv & "  <itp:getUPDList>"
     sEnv = sEnv & "  <itp:INN>" & инн & "</itp:INN>"
     sEnv = sEnv & "  </itp:getметод>"
     sEnv = sEnv & "  </soapenv:Body>"
     sEnv = sEnv & "  </soapenv:Envelope>"

' Send SOAP Request
    Req.send (sEnv)

ответ = Req.responseText
Call h

End Sub


Sub h()

    Dim xml As New MSXML2.DOMDocument60, elem As MSXML2.IXMLDOMElement
     
    xml.async = False 
    xml.LoadXML (ответ)  
    For Each elem In xml.DocumentElement.SelectNodes("//soap:Body/m:getUPDListResponse/m:return/m:НеподписанныйДокумент")
        Debug.Print elem.SelectSingleNode("m:Номер").Text
    Next elem
End Sub
Изменено: Павел Баскаков - 27.10.2022 11:48:05
Всё что мы есть - это результат наших мыслей ©Будда
 
Александр Моторин, Буду пробовать. Возможно это как раз рабочая тема.  
Всё что мы есть - это результат наших мыслей ©Будда
 
просто размножил блок  <m:НеподписанныйДокумент>"..... "</m:НеподписанныйДокумент>"

Код
    a = Split("Номер,Сумма,УИД", ",") ' "список нужніх параметров через запятую без пробела
    u = Split(s, "<m:НеподписанныйДокумент>")
    For k = 0 To UBound(u)
        Debug.Print
        Debug.Print "Документ № " & k
        For i = 0 To UBound(a)
            Debug.Print a(i), get_dan(u(k), a(i))
        Next i
    Next k
поэтому данные одинаковые. лениво менять
Документ № 1
Номер         1234
Сумма         50.7
УИД           1234

Документ № 2
Номер         1234
Сумма         50.7
УИД           1234

Документ № 3
Номер         1234
Сумма         50.7
УИД           1234
Изменено: Александр Моторин - 27.10.2022 11:58:11
Страницы: 1
Наверх