|
как загрузить данные из файла xml | ☑ | ||
---|---|---|---|---|
0
Xelga
14.02.12
✎
17:39
|
Есть файл xml, имеющий такую структуру
- <documents> - <document> <typeName>Счет</typeName> <date>13.12.2011</date> <number>2011/3</number> - <client> <clientShortName>Customer Name</clientShortName> <clientName>Customer Full Name</clientName> <clientId>123456VAT</clientId> <clientAddress>Address Address 2, City, Poland</clientAddress> <clientContractNumber>123456CN</clientContractNumber> </client> - <lines> - <line> <lineNum>1</lineNum> <itemDescription>2011/24/2 (test) proofreading</itemDescription> <itemActivityType>2011/24/2</itemActivityType> <orderedQuantity>3</orderedQuantity> <sum>110.70</sum> <VAT>0.2300</VAT> </line> - <line> <lineNum>2</lineNum> <itemDescription>2011/24/2 (test) - translation</itemDescription> <itemActivityType>2011/24/2</itemActivityType> <orderedQuantity>30</orderedQuantity> <sum>738.00</sum> <VAT>0.2300</VAT> </line> </lines> <TotalLines>2</TotalLines> <TotalSum>848.70</TotalSum> </document> - <document> <typeName>Счет</typeName> <date>22.11.2011</date> <number>draft-2011/1</number> - <client> <clientShortName>Customer Name</clientShortName> <clientName>Customer Full Name</clientName> <clientId>123456VAT</clientId> <clientAddress>Address Address 2, City, Poland</clientAddress> <clientContractNumber>123456CN</clientContractNumber> </client> - <lines> - <line> <lineNum>1</lineNum> <itemDescription>2011/24/1 - перевод - English (United States) [EN-US] » Немецкий [DE]</itemDescription> <itemActivityType>2011/24/1 - перевод - English</itemActivityType> <orderedQuantity>50</orderedQuantity> <sum>615.00</sum> <VAT>0.2300</VAT> </line> - <line> <lineNum>2</lineNum> <itemDescription>2011/24/1 - редактирование - English (United States) [EN-US] » Немецкий [DE]</itemDescription> <itemActivityType>2011/24/1 - редактирование - English</itemActivityType> <orderedQuantity>1</orderedQuantity> <sum>61.50</sum> <VAT>0.2300</VAT> </line> </lines> <TotalLines>2</TotalLines> <TotalSum>676.50</TotalSum> </document> </documents> Нужно написать обработку, которая будет для каждого узла document, создавать Реализацию товаров и услуг, заполнять табличную часть из соответствующего узла lines. Пытаюсь сделать обработку, посмотрела такой пример Чтение = Новый ЧтениеXML; Чтение.ОткрытьФайл(ФайлЗагрузки); Пока Чтение.Прочитать() Цикл Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда ИмяУзла = Чтение.Имя; Сообщить("--" + ИмяУзла); ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда // В примере просто выводим текст в окно сообщений. Сообщить("Текст:" + Чтение.Значение); КонецЕсли; КонецЦикла; Для моего файла по очереди считывается то Имя узла, то Значение. Что-то вообще не могу понять, как мне здесь сделать два цикла, один, который бы создавал документы, другой, который должен заполнять табличную часть? |
|||
1
zzhiraf
14.02.12
✎
17:46
|
Нужно создать файл xsd описания.
|
|||
2
zzhiraf
14.02.12
✎
17:47
|
Если его нет, можно воспользоваться специальными утилитами)
|
|||
3
Xelga
14.02.12
✎
17:50
|
(1) и что потом?
|
|||
4
Xelga
14.02.12
✎
17:51
|
Есть такой файл схемы, это оно?
<?xml version="1.0" encoding="UTF-8"?> $utils.getWindowsNewLine() <documents> #foreach( $invoice in $utils.unwrap(${list})) $utils.getWindowsNewLine() <document> $utils.getWindowsNewLine() <typeName>Счет</typeName> $utils.getWindowsNewLine() <date>$utils.getCommonsDateFormatUtils().format( $utils.getXtrfDateUtils().parseDateString($invoice.displayInvoiceDate), 'dd.MM.yyyy')</date> $utils.getWindowsNewLine() <number>$invoice.displayNumber</number> $utils.getWindowsNewLine() <client> $utils.getWindowsNewLine() <clientShortName>$invoice.customer.name</clientShortName> $utils.getWindowsNewLine() <clientName>$invoice.customer.fullname</clientName> $utils.getWindowsNewLine() <clientId>$invoice.customer.nIPVATEU</clientId> $utils.getWindowsNewLine() <clientAddress>$invoice.customer.address.address $invoice.customer.address.address2, $invoice.customer.address.city, $invoice.customer.address.country.name</clientAddress> $utils.getWindowsNewLine() <clientContractNumber>$invoice.customer.contractNumber</clientContractNumber> $utils.getWindowsNewLine() </client> $utils.getWindowsNewLine() <lines> #set ($count=0) #set ($sum=0) #foreach( $line in $utils.unwrap($invoice.getInvoiceItems())) #set($count = $count+1) $utils.getWindowsNewLine() <line> $utils.getWindowsNewLine() <lineNum>$utils.toInteger($count)</lineNum> $utils.getWindowsNewLine() <itemDescription>$line.getName()</itemDescription> $utils.getWindowsNewLine() #set ($actType = $line.getName()) #set ($index = $actType.indexOf('(')) <itemActivityType>$actType.substring(0, $index).trim()</itemActivityType> $utils.getWindowsNewLine() <orderedQuantity>$utils.toInteger($line.getQuantity())</orderedQuantity> $utils.getWindowsNewLine() #set($sum = $sum+$line.getLineBrutto()) <sum>$line.getLineBrutto()</sum> $utils.getWindowsNewLine() <VAT>$line.getVatRate()</VAT> $utils.getWindowsNewLine() </line> #end $utils.getWindowsNewLine() </lines> $utils.getWindowsNewLine() <TotalLines>$utils.toInteger($count)</TotalLines> $utils.getWindowsNewLine() <TotalSum>$sum</TotalSum> $utils.getWindowsNewLine() </document> #end $utils.getWindowsNewLine() </documents> |
|||
5
andrewks
14.02.12
✎
17:51
|
цикл будет один, просто надо использовать флажок начала документа, устанавливать его в Истину, если встретили <document>
начало элемента. после встречи конца элемента - записывать тек.док, устанавливать флаг в Ложь, и идти дальше |
|||
6
zzhiraf
14.02.12
✎
17:52
|
Потом прочитать содержимое xml во внутренние структуры/массивы структур программы и обработать их как требуется.
|
|||
7
zzhiraf
14.02.12
✎
17:53
|
нет это не файл xml-схемы...
|
|||
8
Xelga
14.02.12
✎
17:54
|
(6) какими функциями это делать?
|
|||
9
zzhiraf
14.02.12
✎
17:55
|
Функциями объекта ФабрикаXDTO - ПрочитатьXML...
|
|||
10
zzhiraf
14.02.12
✎
17:56
|
Получите от поставщика файла xml, файл с xml-схемой (расширение xsd)
|
|||
11
Xelga
14.02.12
✎
17:58
|
Он мне отправил такую схему (4)
|
|||
12
asady
14.02.12
✎
17:59
|
(8) юзай штатный ПостроительDOM
ЧтениеXML = новый ЧтениеXML; ЧтениеXML.ОткрытьФайл(ФайлЗагрузки); СообщениеОбОшибке = "Список записей не найден"; построительДОМ = Новый ПостроительDOM; Попытка ДокументДОМ = построительДОМ.Прочитать(ЧтениеXML); Исключение Сообщить(ОписаниеОшибки()); возврат; КонецПопытки; Если ДокументДОМ.ЭлементДокумента.ИмяУзла<>"documents" Тогда goto ~Err; КонецЕсли; узелdocuments = ДокументДОМ.ЭлементДокумента; СписокЭлементовdocument = узелdocuments.ПолучитьЭлементыПоИмени("document"); Если СписокЭлементовdocument.Количество()=0 Тогда goto ~Err; КонецЕсли; тУзелdocument =СписокЭлементовNodes.Элемент(0); //как пример |
|||
13
zzhiraf
14.02.12
✎
17:59
|
Должно быть что-то типа этого:
|<xs:schema xmlns:ent=""http://v8.1c.ru/8.1/data/enterprise"" xmlns:tns=""http://v8.1c.ru/8.1/data/enterprise/current-config"" xmlns:v8=""http://v8.1c.ru/8.1/data/core"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" targetNamespace=""http://my_exchange/"" attributeFormDefault=""unqualified"" elementFormDefault=""qualified""> | <xs:import namespace=""http://v8.1c.ru/8.1/data/core""/> | <xs:import namespace=""http://v8.1c.ru/8.1/data/enterprise""/> | <xs:complexType name=""CatalogObject.Номенклатура""> | <xs:sequence> | <xs:element name=""IsFolder"" type=""xs:boolean""/> | <xs:element name=""Ref"" type=""tns:CatalogRef.Номенклатура""/> | <xs:element name=""DeletionMark"" type=""xs:boolean""/> | <xs:element name=""Parent"" type=""tns:CatalogRef.Номенклатура""/> | <xs:element name=""Code"" type=""xs:string""/> | <xs:element name=""Description"" type=""xs:string""/> | <xs:element name=""Артикул"" type=""xs:string"" minOccurs=""0""/> | <xs:element name=""НаименованиеПолное"" type=""xs:string"" minOccurs=""0""/> | <xs:element name=""Описание"" type=""xs:string"" minOccurs=""0""/> | <xs:element name=""ФайлКартинки"" type=""xs:string"" minOccurs=""0""/> | <xs:element name=""ОписаниеВФорматеHTML"" type=""xs:string"" minOccurs=""0""/> | <xs:element name=""ДатаЗагрузкиВБазу"" type=""xs:dateTime"" minOccurs=""0""/> | <xs:element name=""Автор"" type=""tns:CatalogRef.Пользователи""/> | </xs:sequence> | </xs:complexType> |</xs:schema> |
|||
14
Kyrales
14.02.12
✎
18:39
|
Воспользуйся функцией считывания в дерево и оттуда уже спокойно создавай свои документы http://infostart.ru/public/84254/
|
|||
15
Xelga
16.02.12
✎
22:48
|
(13) Хочу сделать через фабрикуXDTO, получила схему документа, и что дальше? Ничего не понимаю, как прочитать файл xml, используя схему. Можно какой-нить конкретный пример?
|
|||
16
Xelga
17.02.12
✎
17:15
|
Нашла пример в Простые примеры разработки Габец, Гончаров, делаю по нему
у меня есть схема <?xml version="1.0" encoding="utf-16"?> <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="documents"> <xsd:complexType> <xsd:sequence> <xsd:element name="document"> <xsd:complexType> <xsd:sequence> <xsd:element name="typeName" type="xsd:string" /> <xsd:element name="date" type="xsd:string" /> <xsd:element name="number" type="xsd:string" /> <xsd:element name="client"> <xsd:complexType> <xsd:sequence> <xsd:element name="clientShortName" type="xsd:string" /> <xsd:element name="clientName" type="xsd:string" /> <xsd:element name="clientId" type="xsd:string" /> <xsd:element name="clientAddress" type="xsd:string" /> <xsd:element name="clientContractNumber" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="lines"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" name="line"> <xsd:complexType> <xsd:sequence> <xsd:element name="lineNum" type="xsd:int" /> <xsd:element name="itemDescription" type="xsd:string" /> <xsd:element name="itemActivityType" type="xsd:string" /> <xsd:element name="orderedQuantity" type="xsd:int" /> <xsd:element name="sum" type="xsd:decimal" /> <xsd:element name="VAT" type="xsd:decimal" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="TotalLines" type="xsd:int" /> <xsd:element name="TotalSum" type="xsd:decimal" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Пишу код как в примере Чтение = Новый ЧтениеXML; Чтение.ОткрытьФайл(ФайлСхемы); НовыйПострительДом = Новый ПостроительDOM; НовыйДокументДом = НовыйПострительДом.Прочитать(Чтение); НовыйПостроительСхем = Новый ПостроительСхемXML; НоваяСхема = НовыйПостроительСхем.СоздатьСхемуXML(НовыйДокументДом); НаборСхем = Новый НаборСхемXML; НаборСхем.Добавить(НоваяСхема); НоваяФабрика = Новый ФабрикаXDTO(НаборСхем); Чтение = Новый ЧтениеXML; Чтение.ОткрытьФайл(ФайлЗагрузки); Данные = НоваяФабрика.ПрочитатьXML(Чтение); Если Данные = Неопределено Тогда Возврат; КонецЕсли; Для Каждого Элемент Из Данные.Document Цикл ДатаДок = Элемент.Date; НомерДок = Элемент.Number; Сообщить(НомерДок+" от "+ДатаДок); КонецЦикла; Выдает ошибку "Итератор для значения не определен" В отладке смотрю Данные, там вся структура загрузилась. Но не пойму как надо к ним обращаться? Как потом сделать обход по lines? |
|||
17
vmv
17.02.12
✎
17:22
|
да в каждой типовой есть методы преобразования хмл в дерево.
зачем вообще создавать объекты на лету из хмл, логичнее их проичитать в более удобные структуры(деревья) и юзать уже их. Есть минус, что при большом размере хмл - эта музыка будет вечной, ну то редко бывает, ибо все заполонила попсовая мелкопузая моль. мдя, ето же миста - та пофик, музыку любят все! |
|||
18
vmv
17.02.12
✎
17:30
|
я читаю так, вроде это старый кусок кода из обработки деревьев персонификации, какда писал не помню, зачем тоже - 3 года уже работает и ладно
// Методы обработки XML Процедура ЧитатьXML(ИмяФайлаЧтение, РодительскаяСтрокаXML) // очистим дерево РодительскаяСтрокаXML.Строки.Очистить(); XML = Новый ЧтениеXML(); XML.ОткрытьФайл(ИмяФайлаЧтение); текСтрока = РодительскаяСтрокаXML.Строки.Добавить(); ЗаполнитьЗначенияСвойств(текСтрока, РодительскаяСтрокаXML); текСтрока.Параметр = ИмяФайлаЧтение; СтрокиДерева = текСтрока.Строки; Пока XML.Прочитать() Цикл Если XML.ТипУзла = ТипУзлаXML.Текст Тогда // текст элемента, может быть только после начала элемента // в ТекСтрока сейчас должен быть узел текСтрока.Значение = XML.Значение; ИначеЕсли XML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда СтрокиДерева = ДобавитьУзел(СтрокиДерева, XML, РодительскаяСтрокаXML); ИначеЕсли XML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда // установим родителя Если СтрокиДерева.Родитель.Родитель = Неопределено Тогда // нет узла верхнего уровня СтрокиДерева = СтрокиДерева.Родитель.Строки; Иначе СтрокиДерева = СтрокиДерева.Родитель.Родитель.Строки; КонецЕсли; КонецЕсли; Пока XML.ПрочитатьАтрибут() Цикл текСтрока = СтрокиДерева.Добавить(); ЗаполнитьЗначенияСвойств(текСтрока, РодительскаяСтрокаXML); текСтрока.Параметр = XML.Имя; текСтрока.Значение = XML.Значение; а=1; КонецЦикла; КонецЦикла; XML.Закрыть(); //Дерево = Новый ХранилищеЗначения(ДеревоXML); КонецПроцедуры |
|||
19
zzhiraf
20.02.12
✎
09:29
|
(16) Так если данные в структуру загрузились, то дальше какие проблемы?)
|
|||
20
Xelga
21.02.12
✎
11:21
|
(19) а проблемы 2:
- в файле в структуре document содержатся сведения о документе, если документов несколько, то в цикле всё считывается нормально, а если документ только 1, то выдает ошибку "Итератор для значения не определен", соответственно в цикл не заходит и ничего не считывается - в документе дальше идет параметр lines, где мне надо построчно считать каждую строку Line, а я не знаю как это цикл встроить, как обратиться к этим элементам. Такой у меня цикл чтения данных из файла Для Каждого Элемент Из Данные.Document Цикл ДатаДок = Элемент.Date; НомерДок = Элемент.Number; КлиентСокращенноеНаименование = Элемент.Client.ClientShortName; КлиентПолноеНаименование = Элемент.Client.ClientName; ИНН_КПП = Элемент.Client.ClientId; Адрес = Элемент.Client.ClientContractNumber; КонецЦикла; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |