:: Visual Foxpro, Foxpro for DOS
Как грамотно прочитать XML
Andrey_321
Автор

Сообщений: 109
Откуда: Могилев
Дата регистрации: 21.10.2005
Пробовал через loXML = CreateObject("MSXML2.DOMDocument") не могу добраться до <ATTRIBUTE>.
Хотел через XMLAdapter что то не получается схему документа задать <ATTRIBUTE> хотелось бы как подчиненную таблицу.

XML вида:
<OBJECTSDATASET>
<OBJECT>
<F_OBJECT_ID>1227333</F_OBJECT_ID>
<F_OBJECTGUID>7aa53830-9057-44a0-856e-6eebc1445312</F_OBJECTGUID>
<F_ID>1227334</F_ID>
<F_IDGUID>7e0ce50c-dba2-4ac3-8222-06b9b6443600</F_IDGUID>
<F_LC_STEP>1012</F_LC_STEP>
<F_VERSION_ID>2</F_VERSION_ID>
<F_OBJECT_VER_TYPE>2</F_OBJECT_VER_TYPE>
<F_OBJECT_TYPE>1074</F_OBJECT_TYPE>
<F_OWNER_ID>4</F_OWNER_ID>
<F_OWNERGUID>cad00016-306c-11d8-b4e9-00304f19f545</F_OWNERGUID>
<F_MODIFY_DATE>2016-01-21T06:02:49.843</F_MODIFY_DATE>
<F_LEVEL_ID>2</F_LEVEL_ID>
<F_OBJ_CREATE>2016-01-21T06:02:49.843</F_OBJ_CREATE>
<CAPTION>Oboz1 СБ (Naim1 СБ)</CAPTION>
<ATTRIBUTES>
<ATTRIBUTE>
<F_ATTRIBUTE_ID>9</F_ATTRIBUTE_ID>
<F_INLIST_ID>0</F_INLIST_ID>
<F_STRING_VALUE>Oboz1 СБ</F_STRING_VALUE>
<F_VALUE>Oboz1 СБ</F_VALUE>
</ATTRIBUTE>
<ATTRIBUTE>
<F_ATTRIBUTE_ID>10</F_ATTRIBUTE_ID>
<F_INLIST_ID>0</F_INLIST_ID>
<F_STRING_VALUE>Naim1 СБ</F_STRING_VALUE>
<F_VALUE>Naim1 СБ</F_VALUE>
</ATTRIBUTE>
</ATTRIBUTES>
</OBJECT>
<OBJECT>
<F_OBJECT_ID>4</F_OBJECT_ID>
<F_OBJECTGUID>cad00016-306c-11d8-b4e9-00304f19f545</F_OBJECTGUID>
<F_ID>5</F_ID>
<F_IDGUID>464295e7-fbd4-1290-8ef7-500000000000</F_IDGUID>
<F_LC_STEP>1116</F_LC_STEP>
<F_VERSION_ID>0</F_VERSION_ID>
<F_OBJECT_VER_TYPE>0</F_OBJECT_VER_TYPE>
<F_OBJECT_TYPE>1</F_OBJECT_TYPE>
<F_OWNER_ID>4</F_OWNER_ID>
<F_OWNERGUID>cad00016-306c-11d8-b4e9-00304f19f545</F_OWNERGUID>
<F_MODIFY_DATE>2012-10-26T11:42:50</F_MODIFY_DATE>
<F_LEVEL_ID>2</F_LEVEL_ID>
<F_OBJ_CREATE>2005-03-10T21:02:36</F_OBJ_CREATE>
<CAPTION>Системный администратор</CAPTION>
</OBJECT>
</OBJECTSDATASET>



Исправлено 2 раз(а). Последнее : Andrey_321, 26.01.16 11:49
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
alex;

Сообщений: 2850
Откуда: Москва
Дата регистрации: 23.11.2004
Если поможет код на VBA
Dim xmlDoc As Object 'MSXML2.DOMDocument
Dim xmlNodeContractList As Object 'MSXML2.IXMLDOMNode
Dim xmlNodeContractData As Object 'MSXML2.IXMLDOMNode
Dim xmlNodeSubjectData As Object 'MSXML2.IXMLDOMNode
Dim xmlNode_event_info As Object 'MSXML2.IXMLDOMNode
Dim xmlNode_damage_info As Object 'MSXML2.IXMLDOMNode
Dim xmlNode_refusal_info As Object 'MSXML2.IXMLDOMNode
Dim xmlNodeList As Object 'MSXML2.IXMLDOMNodeList
Dim xml_path As String
Set xmlDoc = CreateObject("MSXML2.DOMDocument") '("MSXML2.DOMDocument.6.0") '
'xml_path = "/nsocuments/nsocument/ns:WayBill/wb:Header/wb:Shipper"
If Not xmlDoc.Load(FileName) Then
MsgBox "Not Loaded"
Exit Sub
End If
Set xmlNodeList = xmlDoc.DocumentElement.SelectNodes("/ContractList/ContractData") 'xml_path)
For Each xmlNodeContractList In xmlNodeList
For Each xmlNodeContractData In xmlNodeContractList.ChildNodes
DataInsCaseExists = False
sf_subject_name = ""
If xmlNodeContractData.BaseName = "SubjectData" Then
For Each xmlNodeSubjectData In xmlNodeContractData.ChildNodes
If xmlNodeSubjectData.BaseName = "event_info" Then
For Each xmlNode_event_info In xmlNodeSubjectData.ChildNodes
If xmlNode_event_info.BaseName = "event_description" Then
If xmlNode_event_info.Text = "" Then
...
If xmlNodeContractData.BaseName = "payments_gov" Then sf_payments_gov = Replace(xmlNodeContractData.Text, ".", ",")
...

Для xml



Исправлено 2 раз(а). Последнее : alex;, 26.01.16 15:04
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
sphinx

Сообщений: 31166
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Andrey_321
Хотел через XMLAdapter что то не получается схему документа задать <ATTRIBUTE> хотелось бы как подчиненную таблицу.

1.В первую строку XML-файла (я его обозвал TEST.XML) следует поместить
<?xml version="1.0" encoding="WINDOWS-1251"?>

2.Создать XSD-схему. Лучший вариант - использовать Visual Studio, а если надо вызывать из одной программы - рекомендую использовать транслятор на Java trang.jar. Строка получения XSD-схемы:
java -jar trang.jar -I xml -O xsd TEST.XML TEST.XSD

3.Создаем курсоры "object" и "attribute":
LOCAL loXAD as XMLAdapter
m.lcFile = 'test.xml'
loXAD = CREATEOBJECT('XMLAdapter')
loXAD.XMLSchemaLocation = FORCEEXT(m.lcFile, 'xsd' )
loXAD.LoadXML(m.lcFile, .T.)
loXAD.Tables(STRCONV("OBJECT", 5)).ToCursor()
loXAD.Tables(STRCONV("ATTRIBUTE", 5)).ToCursor()

4.Проверяем загруженные данные:
SELECT object
BROWSE
SELECT attribute
BROWSE

5.Все необходимые программы выложил в архив: rghost.ru


------------------
"Veni, vidi, vici!"(с)




Исправлено 1 раз(а). Последнее : sphinx, 26.01.16 14:46
Ratings: 0 negative/3 positive
Re: Как грамотно прочитать XML
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Andrey_321
Пробовал через loXML = CreateObject("MSXML2.DOMDocument") не могу добраться до <ATTRIBUTE>.
loXML.selectNodes("//ATTRIBUTE")
Только это не очень поможет в деле разбора иерархии
Andrey_321
Хотел через XMLAdapter что то не получается схему документа задать <ATTRIBUTE> хотелось бы как подчиненную таблицу.
Схему можно сделать в той же VisualStudio. Можно и руками прописать, хотя это несколько утомительно.
Вот схема к приложенному примеру
(в xsd файл её надо записывать в кодировке utf-8, хотя конкретно тут и нету никаких "неанглийских" символов)
С такой схемой более-менее разбирается адаптер. Можно её "уточнять" задавая ограничения по размеру символьных полей, чтобы фокс их не делал memo, да и числовые типы вполне возможно надо сделать "поширше" - студия то предполагала размеры исходя из этих тестовых данных...
Ессно что для полноценной работы в подчинённую таблицу надо добавлять поле ссылающееся на первичный ключ "родительской" таблицы. Для примера я в его качестве взял F_OBJECT_ID - тебе то виднее что там уникальный ключ а что нет. Возможно нужно будет и несколько полей подтягивать - если ключ составной...
Да, сам xml-файл в данном случае должен быть в кодировке UTF-8, или, если он в win1251, то обязательно будет нужна декларация
<?xml version="1.0" encoding="windows-1251"?>
Собственно сам код
loXAD = CREATEOBJECT("XMLAdapter")
loXAD.XMLSCHEMALOCATION = "test.xsd"
loXAD.LOADXML("test.xml",.T.)
loXAD.TABLES(3).TOCURSOR()
BROWSE
loTbl = loXAD.TABLES(1)
loFld = CREATEOBJECT("XMLField")
loFld.ALIAS = "parent_id"
loFld.DATATYPE = "I"
loFld.XMLNAMEISXPATH = .T.
loFld.XMLNAME = STRCONV("../../F_OBJECT_ID", 5)
loTbl.FIELDS.ADD(m.loFld, m.loFld.XMLNAME)
loTbl.TOCURSOR()
BROWSE


------------------
WBR, Igor
Ratings: 0 negative/2 positive
Re: Как грамотно прочитать XML
alex;

Сообщений: 2850
Откуда: Москва
Дата регистрации: 23.11.2004
Я для работы с xsd использовал "Oxygen XML Editor" - она генерит xsd, который потом удобно редактировать.
Она же показывает где xml не удовлетворяет схеме. Удобно.
ее можно получить бесплатно на три месяца и несколько раз

www.oxygenxml.com
Ratings: 0 negative/1 positive
Re: Как грамотно прочитать XML
Andrey_321
Автор

Сообщений: 109
Откуда: Могилев
Дата регистрации: 21.10.2005
Спасибо за оперативную помощь буду пробовать!
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Andrey_321
Автор

Сообщений: 109
Откуда: Могилев
Дата регистрации: 21.10.2005
Igor Korolyov
Собственно сам код
loXAD = CREATEOBJECT("XMLAdapter")
loXAD.XMLSCHEMALOCATION = "test.xsd"
loXAD.LOADXML("test.xml",.T.)
loXAD.TABLES(3).TOCURSOR()
BROWSE
loTbl = loXAD.TABLES(1)
loFld = CREATEOBJECT("XMLField")
loFld.ALIAS = "parent_id"
loFld.DATATYPE = "I"
loFld.XMLNAMEISXPATH = .T.
loFld.XMLNAME = STRCONV("../../F_OBJECT_ID", 5)
loTbl.FIELDS.ADD(m.loFld, m.loFld.XMLNAME)
loTbl.TOCURSOR()
BROWSE

Все сделал не пойму почему не работает на LOADXML парсер выдает ошибку "не удается найти указанный объект строка:0 позиция:0"?
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
sphinx

Сообщений: 31166
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Andrey_321
Все сделал не пойму почему не работает

А мой код пробовал? Ни Visual Studuo не надо, ни ручками рисовать XSD схему. Все этапы получения нужных курсоров можно оформить в одной программе.


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/1 positive
Re: Как грамотно прочитать XML
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Очевидно, какой-то косяк в xsd или в xml файле.
В архиве все файлы которые у меня работают.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Andrey_321
Автор

Сообщений: 109
Откуда: Могилев
Дата регистрации: 21.10.2005
Я вообще не понимаю почему но loXAD.LOADXML([D:\MUSOR\disk\IPS-LM-TP-2016012115054651636590.xml],.T.) не работает а если положить в корень loXAD.LOADXML([IPS-LM-TP-2016012115054651636590.xml],.T.) то все ОК!? Как тогда указывать путь для xml (CD - что ли)?



Исправлено 2 раз(а). Последнее : Andrey_321, 29.01.16 11:10
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
sphinx

Сообщений: 31166
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Andrey_321
Как тогда указывать путь для xml

Да хоть где лежит. Не судьба программно (если по полному пути не взлетает, а времени разбираться нет) - перейти в нужный каталог?


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Asmodey

Сообщений: 49
Откуда: Ноябрьск
Дата регистрации: 25.05.2007
rt1 = ADDBS(SYS(5)+SYS(2003))+"x.xml"
rt_str = ""
oxml = CREATEOBJECT('msxml.domdocument')
oxml.load(rt1)
FOR lvl_1_count = 0 TO oxml.documentelement.childnodes.length-1
IF oxml.documentelement.childnodes.length==1
rt_str = rt_str + oxml.documentelement.childnodes(lvl_1_count).nodename + " = " + oxml.documentelement.childnodes(lvl_1_count).text + CHR(13) + CHR(10)
ENDIF
* второй уровень
FOR lvl_2_count = 0 TO oxml.documentelement.childnodes(lvl_1_count).childnodes.length-1
IF oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes.length==1
rt_str = rt_str + ' ' + oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).nodename + " = " + oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).text + CHR(13) + CHR(10)
ENDIF
* третий уровень
FOR lvl_3_count = 0 TO oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes.length-1
IF oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).childnodes.length==1
rt_str = rt_str + ' ' + oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).nodename + " = " +oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).text + CHR(13) + CHR(10)
ENDIF
* четвёртый уровень
FOR lvl_4_count = 0 TO oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).childnodes.length-1
IF oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).childnodes(lvl_4_count).childnodes.length==1
rt_str = rt_str + ' ' + oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).childnodes(lvl_4_count).nodename + " = " + oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).childnodes(lvl_4_count).text + CHR(13) + CHR(10)
ENDIF
ENDFOR
ENDFOR
ENDFOR
* а так можно прочитать атрибуты который неходятся внутри тэгов
* такие например <zglv type="Subekti" version="1.2" date="21.03.2014" />
FOR lvl_1_attrib_count = 0 TO oxml.documentelement.childnodes(lvl_1_count).attributes.length-1
rt_str = rt_str + " " + oxml.documentelement.childnodes(lvl_1_count).attributes(lvl_1_attrib_count).name + " = " + oxml.documentelement.childnodes(lvl_1_count).attributes(lvl_1_attrib_count).text + CHR(13) + CHR(10)
ENDFOR
ENDFOR
RELEASE oxml
=STRTOFILE(rt_str, ADDBS(SYS(5)+SYS(2003))+"x.txt")
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
ssa

Сообщений: 12999
Откуда: Москва
Дата регистрации: 23.03.2005
Жуть. Но кое-что понравилось:
1. ....length==1
2. атрибуты который неходятся




------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Asmodey

Сообщений: 49
Откуда: Ноябрьск
Дата регистрации: 25.05.2007
ssa
Жуть. Но кое-что понравилось:
1. ....length==1
2. атрибуты который неходятся


если есть универсальное решение как обойти всё дерево проще - буду рад увидеть
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
ssa

Сообщений: 12999
Откуда: Москва
Дата регистрации: 23.03.2005
Asmodey
ssa
Жуть. Но кое-что понравилось:
1. ....length==1
2. атрибуты который неходятся


если есть универсальное решение как обойти всё дерево проще - буду рад увидеть
1. Да я, в общем-то, не про обход дерева.
2. Писать свой парсер XML - задача из области изобретения велосипедов.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Crispy

Сообщений: 18571
Дата регистрации: 16.05.2005
Asmodey
если есть универсальное решение как обойти всё дерево проще - буду рад увидеть

А в чем суть проблемы-то? Что нужно в итоге?


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Asmodey
если есть универсальное решение как обойти всё дерево проще - буду рад увидеть
Ну как минимум не писать километровые тормознутые и бредовые
oxml.documentelement.childnodes(lvl_1_count).childnodes(lvl_2_count).childnodes(lvl_3_count).childnodes(lvl_4_count).childnodes
пользоваться foreach, XPath запросами SelectNodes/SelectSingleNode - что частично видно выше в коде Алексея (alex; )

Хотя конкретно для указанного XML с его разбором вполне справляется XMLAdapter. А для большинства "сложных" XML-ей можно воспользоваться 2-х ступенчатой процедурой - сначала при помощи XSLT преобразовать эту сложную иерархическую структуру в простой набор "плоских таблиц" - заодно добавив куда надо поля "внешних ключей" (данные всё ещё в XML-е), а потом уже напрямую, безо всяких шаманств загрузить этот новый простой XML в XMLAdapter и получить фоксовые курсоры.


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 04.02.16 15:00
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
dafni_2004

Сообщений: 86
Дата регистрации: 17.11.2005
Добрый день - навязали нам тут работку ((
подскажите как лучше разобрать XML - сейчас просто разбираю через Fopen() .... но кто знает что будет
rghost.ru
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Такой сложносвязанный - вероятно лучше через XMLDOM (наподобии того что выше alex; писал) - если с адаптером заморачиваться то получится штук 15 курсоров, хотя оно скорее всего и не нужно столько.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как грамотно прочитать XML
sphinx

Сообщений: 31166
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
ssa
Писать свой парсер XML - задача из области изобретения велосипедов.

Именно так. К тому же XML (право, не знал, пока не столкнулся с проблемой Татьяны Агафоновой) еще и через SAX можно контролировать правильность. Вручную тоже можно, но.. с мягким знаком.


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 22 (Гостей: 22)

© 2000-2024 Fox Club 
Яндекс.Метрика