как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
Уважаемые знатоки. Прошу мне помочь в решении одной задачи.
есть веб сервис по POST запросу -который возвращает данные в формате JSON и эти данные необходимо записать в таблицу dbf возможно этот вопрос обсуждался и модераторов прошу простить, я не знаю как и где искать именно это решение всем заранее спсибо |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
И в чём конкретно проблема?
Как искать - можно вообще через гугл, а можно нажать красную ссылку сверху или снизу сообщений. Только диапазон дат лучше расширить - не за месяц искать а за всё время... Как работать с веб-сервисом - поиск по словам "сервис", "POST", "XMLHTTP". Как "разобрать" строку с json-ом - поиск по словам "JSON". Как "записать в таблицу" - открыть хелп и читать про команду INSERT-SQL. "Всё вместе" - ну написать в форум работа - может быть кто то за вас и напишет всю программу целиком ------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
Igor Korolyov Спасибо за ответ.
попробую объяснить в чем проблема. есть веб сервис (wsdl) по локальному адресу идет запрос из этого веб сервиса (результат полученных данных из веб сервиса я сохранил в aaa.xml) и полученный результат необходимо сохранить в курсор. вот кусочек кода: o=CREATEOBJECT("MSSoap.SoapClient30") o.MSSoapInit("http://172.106.100.25:8080/Service?wsdl") loexception=NULL tt='' TRY tt=o.GetAccountData(pin) CATCH TO loexception MESSAGEBOX(loexception.MESSAGE) MESSAGEBOX(loexception.ERRORNO) ENDTRY IF ISNULL(loexception) lcXML=tt.ITEM(0).parentnode.XML LOCAL oXA AS XMLADAPTER oXA = CREATEOBJECT("XMLAdapter") oXA.LOADXML(lcXML,.F.,.T.) oXA.TABLES[1].TOCURSOR(.F.,"testdata") ENDIF RELEASE o CLOSE DATABASES вот при создании курсора выходит сообщение Index or expression does not match an existing member of the collection. да на этом форуме есть наверняка ответ. помогите правильно сформулировать поиск или ссылку дайте плз а еще лучше подсказать какой строки не хвататет в этом коде |
Re: как заполнить таблицу из веб сервиса | |
---|---|
rvc44 Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Не факт, что объект "MSSoap.SoapClient30" будет успешно создан в вашей системе. По крайней мере, в комплекте с VFP соответствующий класс не устанавливается по умолчанию. А Вы не пробовали обращаться к web-сервису по-другому:
|
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
объект "MSSoap.SoapClient30" создан успешно. в комплекте VFP по умолчанию не было этого класса, но я до установил соответствующий патч и все заработало. просто так как я в первые сталкиваюсь с веб сервисом, и теперь я кажется понял как надо правильно сформулировать вопрос к знатокам. веб сервис возвращает данные в следующей структуре: <GetAccountDataResult> <a:AccountRecords> <a:Activity/> <a:AddSalary>0.00</a:AddSalary> <a:Category>00 |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
объект "MSSoap.SoapClient30" создан успешно. в комплекте VFP по умолчанию не было этого класса, но я до установил соответствующий патч и все заработало. просто так как я в первые сталкиваюсь с веб сервисом, и теперь я кажется понял как надо правильно сформулировать вопрос к знатокам. веб сервис возвращает данные в следующей структуре: <GetAccountDataResult> <a:AccountRecords> <a:Activity/> <a:AddSalary>0.00</a:AddSalary> <a:Category>001</a:Category> <aateBegin>2007-02-14T00:00:00</aateBegin> <aateEnd>2007-08-09T00:00:00</aateEnd> <a:HighlandRate/> <a:INN>00103199610159</a:INN> </a:AccountRecords> <a:ActuarialCoefficient>0.04</a:ActuarialCoefficient> <a:CauseOfError>NO_ERRORS</a:CauseOfError> <a:FirstName>Улукбек</a:FirstName> <a:Flat/> <a:House>38</a:House> <a:LastName>Самыйбеков</a:LastName> <a:Patronymic>Сатарбекович</a:Patronymic> <a:Place>БИШКЕК</a:Place> <a:Street>ыоларолр</a:Street> <a:TotalStanding>08/07/10</a:TotalStanding> <a:ZIPCode>720000</a:ZIPCode> </GetAccountDataResult> То есть исходя из этого я не правильно создаю курсор из этих данных, так как данные имеют не простую, а вложенную схему Внимание вопрос как из этого заполненого адаптера вытащить данные в курсор |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Он (сервис) возвращает объект с интерфейсом IXMLDOMNodeList? Если нет (что скорее всего так и есть), то зачем пытаться применить к нему .item(0)?
Откуда взята строка "<GetAccountDataResult> ....."? Это то что находится в переменной tt после завершения вызова, или это то что находится в переменной lcXML после соответствующей команды присвоения? На какую команду выдаётся указанная ошибка? XMLAdapter сам по себе не сможет "разобрать" более/менее сложную структуру, тем более без схемы. Но ему можно "подсказать" как это делать - для постых случаев хватит и xsd схемы, для более сложных (в т.ч. и тех где нужно брать данные из разных узлов/уровней иерархии XML-домуента) - надо "вручную" настраивать XMLTables/XMLFields. P.S. На сегодняшний день лучше не использовать MSSOAP компоненту, заменив её на "прямой" запрос через XMLHTTP. Как показано (хотя и весьма многословно) в примере Романа. ------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
Доброго времени суток! Спасибо за отзыв! GetAccountDataResult - это результат который возвращается при вызове метода GetAccountData(ПИН) если честно я не разобрался что и как именно он(сервис) возвращает. мне кажется он возвращает обьект. присваивая к переменной lcXML=tt.ITEM(0).parentnode.XML такое значение и сохраняя его в xml-файл я получил такой результат <GetAccountDataResult> <a:AccountRecords> ... </a:AccountRecords> <a:ActuarialCoefficient>0.04</a:ActuarialCoefficient> <a:CauseOfError>NO_ERRORS</a:CauseOfError> <a:FirstName>Улукбек</a:FirstName> <a:Flat/> <a:House>38</a:House> <a:LastName>Самыйбеков</a:LastName> <a:Patronymic>Сатарбекович</a:Patronymic> <a:Place>БИШКЕК</a:Place> <a:Street>ыоларолр</a:Street> <a:TotalStanding>08/07/10</a:TotalStanding> <a:ZIPCode>720000</a:ZIPCode> </GetAccountDataResult> мне сейчас нужен доступ к вложенным данным в <a:AccountRecords> <a:Activity/> <a:AddSalary>0.00</a:AddSalary> <a:Category>001</a:Category> <aateBegin>2007-02-14T00:00:00</aateBegin> <aateEnd>2007-08-09T00:00:00</aateEnd> <a:HighlandRate/> <a:INN>00103199610159</a:INN> </a:AccountRecords> Если честно у меня опыта писать на лисе маленький. время от времени в зависимости от задачи прибегаю к кодам. соответственно как работает xml-адаптер имею мало представления подскажите как мне записать в курсор данные из <a:AccountRecords> ... </a:AccountRecords> Спасибо заранее! |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Ну раз речь не про JSON а таки про XML, то в поиск по "XMLAdapter" - примеров хватает. Правда таким образом как делаешь ты, скорее всего не получится работать - я не вижу в твоём примере XML-я определений пространств имён, нечто типа xmlns:a="http://www.example.org/some" - без этого XML не является корректным... Но если на самом деле они там (в реальном XML-е) есть, то разобрать можно. Если не нужно в куроср вынимать данные из разных уровней иерархии, то даже не придётся париться с ручным прописыванием XMLName-ов для объектов XMLField - достаточно будет подготовить корректную xsd схему для твоей структуры.
------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
<GetAccountDataResult xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/PersonalAccountService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:AccountRecords> <a:AccountRecord><a:Activity/><a:AddSalary>0.00</a:AddSalary><a:Category>001</a:Category><aateBegin>2016-12-01T00:00:00</aateBegin><aateEnd>2016-12-31T00:00:00</aateEnd></a:AccountRecord> <a:AccountRecord><a:Activity/><a:AddSalary>0.00</a:AddSalary><a:Category>001</a:Category><aateBegin>2007-02-14T00:00:00</aateBegin><aateEnd>2007-08-09T00:00:00</aateEnd></a:AccountRecord> ... </a:AccountRecords> <a:ActuarialCoefficient>0.04</a:ActuarialCoefficient> <a:CauseOfError>NO_ERRORS</a:CauseOfError> <a:FirstName>Улукбек</a:FirstName> <a:Flat/> <a:House>38</a:House> <a:LastName>Самыйбеков</a:LastName> <a:Patronymic>Сатарбекович</a:Patronymic> <a:Place>БИШКЕК</a:Place> <a:Street>ыоларолр</a:Street> <a:TotalStanding>08/07/10</a:TotalStanding> <a:ZIPCode>720000</a:ZIPCode> </GetAccountDataResult> Спасибо за помощь! попробую создать схему и через него |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Ну это совсем другое дело - тут пространства имён на месте По идее адаптер (после подсовывания ему корректной схемы) без проблем достанет то что внутри AccountRecords. Вот с тем что внутри корневого узла GetAccountDataResult будут вопросы... Но в принципе всё решаемо - если и не "чисто схемой", то прописыванием нужных xpath путей для XMLName соответствующих объектов. В крайнем случае можно и вручную брать данные через метод SelectSingleNode - благо XML возвращается уже сразу в виде DOM-а, т.е. объекта из состава MSXML парсера...
------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
[attachment 26857 xml_xsd.rar]у меня совсем не получается все время выходит ошибка Index or expression does not match an existing member of the collection
веб сервис возвращает данные в объект tt и я присваиваю к переменной lcXML данные из объекта tt и сохраняю в файл bbb.xml (для проверки что веб сервис выплевывает) pin = '20212198701159' SET TALK OFF o=CREATEOBJECT("MSSoap.SoapClient30") o.MSSoapInit("http://172.16.100.25:8080/RestManagerFundsService?wsdl") loexception=NULL tt='' TRY tt=o.GetAccountData(pin) CATCH TO loexception MESSAGEBOX(loexception.MESSAGE) MESSAGEBOX(loexception.ERRORNO) ENDTRY CREATE CURSOR AccountRecord(; Activity char(3),; AddSalary double(2),; DateBegin DATE, DateEnd date,; HighlandRate char(3),; INN char(14),; Income double(2),; IndexationCoefficient double(2),; MedicineFundSum double(2),; Month integer,; NumSF char(14), OKPO char(8), ; PFUnitedPart double(2), ; Payer char(50), ; PensionFundPaymentSum double (2), ; PensionFundSum double (2), ; PerEmpr double (2), ; Percent double (2), ; PreEmpe double (2), ; Privilege char(10), ; RUSF char(3), ; SFUnitedPart double (2),; SP2 double (2), ; Salary double (2), ; SalaryFull double (2), ; SavingFundPaymentSum double (2), ; SavingFundSum double (2), ; Standing char(10), ; SumEmpe double (2), ; SumEmpr double (2), ; Voluntary char(1),; Year integer) IF ISNULL(loexception) lcXML=tt.ITEM(1).parentnode.XML STRTOFILE(lcXML,'bbb.xml') LOCAL oXA as XMLAdapter, oXT as XMLTable, oXF as XMLField oXA = CREATEOBJECT("XMLAdapter") oXA.LoadXML(lcXML,.F.,.T.) oXA.XMLSchemaLocation="lss.xsd" IF USED('AccountRecord') USE IN AccountRecord ENDIF oXA.TABLES[2].TOCURSOR(.F.,"AccountRecord") ENDIF RELEASE o Я приатачил файл bbb.xml и lss.xsd Уважаемые господа. Помогите где у меня чего не хватает. |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Схема некорректная (регистр, пространства имён). Кроме того, в таком виде она слишком сложная, не уверен что адаптер сможет разобрать... Ну разве что выкинуть описание полей вне узла AccountRecords (т.е. использовать "неполную" схему) и подшаманить с префиксом у корневого элемента (он получается не из того пространства имён что все прочие элементы)... Впрочем, это сложный и муторный путь
Если же вынуть только узел AccountRecords, то всё станет значительно проще... Там даже тривиальным XMLTOCURSOR() вообще без схемы можно получить курсор с данными. Ну, конечно, и через адаптер с корректной схемой (в данном случае она будет простой) можно... Из MXSML2.DomDocument объекта выбор только XML текста для узла узла AccountRecords делается кодом типа
P.S. сам курсор ни так ни этак делать не обязательно - это если бы мы работали не через схему, тогда да - но это совсем другой вариант, и он слишком "многословный" - там нужно пустой курсор погрузить в адаптер через AddTableSchema, а потом вручную перебивать все XMLName для получившихся XMLTable (что ещё пол беды) и XMLField (а тут то как раз писанины...) Примеры как работать по такой схеме есть на форуме. Из плюсов - можно вынуть в этот же курсор данные из узлов вне списка - т.е. FirstName, LastName - но я бы не стал так делать, всё ж это мастер-детали схема, и сливать все поля в одну таблицу не очень хорошо... ------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
переменная loDOM каким образом должна объявляться каким типом? СПС за ранее |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Фокс нетипизированный язык, не нужно ему ничего указывать про типы.
Эта переменная у меня приведена чисто для иллюстрации идеи - какой метод объекта нужно использовать. Как получить ссылку на такой объект (хотя тут я не могу ничего гарантировать - это лишь предположение, на основании того как в твоём коде был получен текст xml-документа) написано чуть ниже. ------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
U_LooK Автор Сообщений: 19 Откуда: Bishkek Дата регистрации: 04.12.2009 |
Я уже совсем запутался. Поставлю вопрос иначе у меня есть некий веб сервис из которого я получаю данные следующим образом pin = '20212198701159' o=CREATEOBJECT("MSSoap.SoapClient30") o.MSSoapInit("http://172.16.100.25:8080/RestManagerFundsService?wsdl") lcXML=tt.ITEM(0).parentnode.XML На всякий случай полученный XML файл сохраняю на диск следующим образом STRTOFILE(lcXML,'aaa.xml') внутри сохраненного файла появились следующие строки <GetAccountDataResult xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/PersonalAccountService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:AccountRecords> <a:AccountRecord> <a:Activity>999</a:Activity> <a:AddSalary>0.00</a:AddSalary> <a:Category>001</a:Category> <aateBegin>2006-09-01T00:00:00</aateBegin> <aateEnd>2006-09-30T00:00:00</aateEnd> <a:HighlandRate/> </a:AccountRecord> <a:AccountRecord> <a:Activity/> <a:AddSalary>0.00</a:AddSalary> <a:Category>001</a:Category> <aateBegin>2010-08-01T00:00:00</aateBegin> <aateEnd>2010-08-31T00:00:00</aateEnd> <a:HighlandRate/> </a:AccountRecord> </a:AccountRecords> <a:ActuarialCoefficient>0.04</a:ActuarialCoefficient> <a:CauseOfError>NO_ERRORS</a:CauseOfError> <a:FirstName>Кенжебек</a:FirstName> <a:Flat/> <a:House>12</a:House> <a:LastName>Киязов</a:LastName> <a:Patronymic>Кадырбекович</a:Patronymic> <a:Place/> <a:Street>Онбир-Жылга у Калмурса</a:Street> <a:TotalStanding>06/10/02</a:TotalStanding> <a:ZIPCode>722203</a:ZIPCode> </GetAccountDataResult> Теперь мне надо из этого веб сервиса получить таблицу или курсор с данными по столбцам из узла <a:AccountRecord> то есть курсор должен иметь следующие столбцы с данными AddSalary, Category, DateBegin, DateEnd, HighlandRate Может для кого то тривиальная задача, но для меня сложновато. Люди добрые подскажите или напишите какие там должны быть строки кода чтобы решить мою маленькую задачу. Может быть поможет... я долго копался в самом веб сервисе и я там откапал xsd схему вот так она выглядит <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/PersonalAccountService" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/PersonalAccountService"> <xs:complexType name="PersonalAccountData"> <xs:sequence> <xs:element minOccurs="0" name="AccountRecords" nillable="true" type="tns:ArrayOfAccountRecord"/> <xs:element minOccurs="0" name="ActuarialCoefficient" type="xs:decimal"/> <xs:element minOccurs="0" name="CauseOfError" type="tns:ServiceErrors"/> <xs:element minOccurs="0" name="FirstName" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="Flat" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="House" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="LastName" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="Patronymic" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="Place" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="Street" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="TotalStanding" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="ZIPCode" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="PersonalAccountData" nillable="true" type="tns:PersonalAccountData"/> <xs:complexType name="ArrayOfAccountRecord"> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" name="AccountRecord" nillable="true" type="tns:AccountRecord"/> </xs:sequence> </xs:complexType> <xs:element name="ArrayOfAccountRecord" nillable="true" type="tns:ArrayOfAccountRecord"/> <xs:complexType name="AccountRecord"> <xs:sequence> <xs:element minOccurs="0" name="Activity" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="AddSalary" type="xs:decimal"/> <xs:element minOccurs="0" name="Category" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="DateBegin" type="xs:dateTime"/> <xs:element minOccurs="0" name="DateEnd" type="xs:dateTime"/> <xs:element minOccurs="0" name="HighlandRate" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="AccountRecord" nillable="true" type="tns:AccountRecord"/> <xs:simpleType name="ServiceErrors"> <xs:restriction base="xs:string"> <xs:enumeration value="NO_ERRORS"/> <xs:enumeration value="PIN_INCORRECT"/> <xs:enumeration value="PIN_NOTFOUND"/> <xs:enumeration value="PIN_INACTIVE"/> <xs:enumeration value="MK_WRONG"/> <xs:enumeration value="INTERNAL_ERROR"/> <xs:enumeration value="ACTUARIAL_COEF_NOTFOUND"/> </xs:restriction> </xs:simpleType> <xs:element name="ServiceErrors" nillable="true" type="tns:ServiceErrors"/> </xs:schema> Я тут везде указываю только 5 полей схемы на самом деле там более 20 полей. И так мой пост так многословен. Спасибо всем заранее. |
Re: как заполнить таблицу из веб сервиса | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Ещё раз по буквам:
------------------ WBR, Igor |
Re: как заполнить таблицу из веб сервиса | |
---|---|
of63 Сообщений: 25161 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
() Вобще, ... я нифика не понял, в каждой строке - ничего, хоть комментариями бы снабдил...
|
Re: как заполнить таблицу из веб сервиса | |
---|---|
Simple777 Сообщений: 33855 Дата регистрации: 05.11.2006 |
"В каждой строчке только точки после буквы л...
|
Re: как заполнить таблицу из веб сервиса | |
---|---|
of63 Сообщений: 25161 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
() Что начиналась с буквы "Л", заканчиваясь мягким знаком
|
© 2000-2024 Fox Club  |