Имя: Пароль:
1C
 
Чтение xml.
0 Блондинистая Ромашка
 
10.03.10
09:05
Понимаю, тема заезженная.
но я нашла либо последовательно считываемый документ, либо теги с текстом. А вот такой файлик как разобрать?
<Zagolovok>
- <Document Vid="InMaterials" sost="move" date="2010-01-29" number="00000002" contr="00000039" dogovor="000001" comment="1/3 "БД для ЭОКС"" sklad="00001" VidPost="post" InDokNumber="403" InDokDate="2010-01-29">
 <Stroka nomenklatura="000000042" kolvo="1" price="3496" sum="3496" nds="533.29" />
 <Stroka nomenklatura="1111111" kolvo="2" price="1111" sum="1111" nds="11.11" />
 </Document>
- <Document Vid="InMaterials" sost="move" date="2010-01-31" number="00000003" contr="00000712" dogovor="000001" comment="1/4" sklad="00001" VidPost="post" InDokNumber="52" InDokDate="2010-01-31">
 <Stroka nomenklatura="000000024" kolvo="154.46" price="19.89" sum="3072.96" nds="468.76" />
 </Document>
</Zagolovok>

Тут и теги и атрибуты. В Книге знаний есть статейка, но там разбирается как текстовый файл. Выдает мне ошибку
неожиданный тег <Zagolovok><Document> в строке 3
Сообщить("Неожиданный тег "+xml_ИмяТега+" в строке "+xml_file.line); a=10/0;
Деление на 0.

Если XMLParser пользоваться, то вот так я верхнюю строку с общими параметрами дока могу забрать
   ТипТега = Документ.Спуститься();    
   ТипТега = Документ.Спуститься();
   СвойстваТекущегоУзла    =    Документ.СвойстваТекущегоУзла;
   ИмяТега                    =    СвойстваТекущегоУзла.Имя;    
   
   Если    ИмяТега    =    "Document"    Тогда  
       Сообщить(ИмяТега);
       ТипТега = Документ.Спуститься();
       Пока ТипТега < 3 Цикл
           Для СчАтрибутов = 0 По СвойстваТекущегоУзла.КоличествоАтрибутов - 1 Цикл
               ИмяАтрибута    =    СвойстваТекущегоУзла.НаименованиеАтрибута(СчАтрибутов);
               Если    ИмяАтрибута = "Vid"    Тогда
                   ВидДока        =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);
               ИначеЕсли    ИмяАтрибута = "sost" Тогда
                   СостояниеДока        =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);
               ИначеЕсли    ИмяАтрибута = "date" Тогда
                   ДатаДока            =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);  
               ИначеЕсли    ИмяАтрибута = "number" Тогда
                   НомерДока        =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);    
               ИначеЕсли    ИмяАтрибута = "contr" Тогда
                   КодКонтрагента        =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);
               ИначеЕсли    ИмяАтрибута = "dogovor" Тогда
                   КодДоговора        =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);
               ИначеЕсли    ИмяАтрибута = "comment" Тогда
                   Коммент        =    СвойстваТекущегоУзла.ЗначениеАтрибута(СчАтрибутов);
               КонецЕсли;  
           КонецЦикла;      
           
           Сообщить(ВидДока+"    "+ДатаДока+"    "+НомерДока+"    "+КодКонтрагента+"    "+КодДоговора+"    "+Коммент);
           
           ТипТега = Документ.Спуститься();  
           СвойстваТекущегоУзла    =    Документ.СвойстваТекущегоУзла;
           ИмяТега                    =    СвойстваТекущегоУзла.Имя;    
           Сообщить(ИмяТега);

Ну а на подчиненный тег stroka уже не получается спуститься :(
Может через узлы? А как тогда быть с атрибутами?
1 Ёпрст
 
гуру
10.03.10
09:08
2 Блондинистая Ромашка
 
10.03.10
09:09
(1) читала, не нравится
почему я должна разбирать xml как тектовый, если есть специальные средства?
3 Ёпрст
 
гуру
10.03.10
09:11
(2) потому,что так быстрее
4 Ёпрст
 
гуру
10.03.10
09:12
+3 да и xml - всю жизнь был обычным текстовым файлом..
5 Блондинистая Ромашка
 
10.03.10
09:13
(3) тогда ищем косяк в коде

       xml_ОткрытьФайл(стрИмяФайла);
       
       xml_Прочитать("<Zagolovok>");
       
       
       Пока xml_Прочитать("<Document")=1 Цикл
           сч=сч+1; //Для ускорения
           Если сч%1000=0 Тогда       //Для ускорения
                   ЗафиксироватьТранзакцию(); //Для ускорения
                   НачатьТранзакцию();//Для ускорения
           КонецЕсли;//Для ускорения
           
           Если xml_ИмяТега="</Document>" Тогда
                   Прервать;
           КонецЕсли;
           
           ВидДока=xml_ПолучитьАтрибут("Vid");
           СостояниеДока=xml_ПолучитьАтрибут("sost");
           ДатаДока=xml_ПолучитьАтрибут("date");
           НомерДока=xml_ПолучитьАтрибут("number");
           КодКонтрагента=Число(xml_ПолучитьАтрибут("contr"));
           КодДоговора=Число(xml_ПолучитьАтрибут("dogovor"));
           Коммент=xml_ПолучитьАтрибут("comment");
           КодСклада=Число(xml_ПолучитьАтрибут("sklad"));
           ВидПоступления=Число(xml_ПолучитьАтрибут("VidPost"));
           НомерДокВход=xml_ПолучитьАтрибут("InDokNumber");  
           ДатаДокВход=xml_ПолучитьАтрибут("InDokDate");
           
           Сообщить(ВидДока + "    " + СостояниеДока + "    " + ДатаДока + "    " + НомерДока);
           
                           
           Пока xml_Прочитать("<Stroka")=1 Цикл  
               Если xml_ИмяТега="/>" Тогда
                       Прервать;
               КонецЕсли;    
               
               
               КодНоменклатуры=xml_ПолучитьАтрибут("nomenklatura");
               Колво=xml_ПолучитьАтрибут("kolvo");
               Цена=xml_ПолучитьАтрибут("price");
               Сумма=xml_ПолучитьАтрибут("sum");
               НДС=xml_ПолучитьАтрибут("nds");
               
               Сообщить(КодНоменклатуры+"    "+Колво+"    "+Цена+"    "+Сумма+"    "+НДС);
           КонецЦикла;
               
       КонецЦикла;     //по элементам XML
       
       xml_Закрыть();

Ошибку выдает следующую:
Неожиданный тег <Zagolovok><Document> в строке 3
Сообщить("Неожиданный тег "+xml_ИмяТега+" в строке "+xml_file.line); a=10/0;
Деление на 0.
6 Just4Fun
 
10.03.10
09:18
ХМЛДок = СоздатьОбъект("MSXML2.DOMDocument");
Корень = ХМЛДок.documentElement; //позиционируемся на корневой элемент документа
ДочерниеУзлы = Корень.childNodes;       //узлы Док, т.е. отдельные документы
СписокЭлементовСправочники = ХМЛДок.getElementsByTagName("Справочники");
СписокЭлементовСпецификации = ХМЛДок.getElementsByTagName("Спецификации");
   

   Для к = 0  по ХМЛСпецификации.length - 1 Цикл
       ХМЛСпецификация = ХМЛСпецификации.item(к);
       ....................
       ДокСпецификация.ДатаДок = ХМЛСпецификация.attributes.getNamedItem("Дата").value;
       ДокСпецификация.НомерДокОУ = СокрЛП(ХМЛСпецификация.attributes.getNamedItem("НомерДок").value);
       ДокСпецификация.Номер = ХМЛСпецификация.attributes.getNamedItem("НомерСпецификации").value;
       Для к2 = 0 По ХМЛСпецификация.childNodes.length - 1 Цикл
           ХМЛЭлемент = ХМЛСпецификация.childNodes.item(к2);
           Если ХМЛЭлемент.nodeName = "Шапка" Тогда
               РеквизитыШапки = ХМЛЭлемент.childNodes;
               Для к3 = 0 По РеквизитыШапки.length - 1 Цикл
                              ...............................
               КонецЦикла;
           КонецЕсли;
       КонецЦикла;
7 Just4Fun
 
10.03.10
09:21
+(6) Пользуюсь такой конструкцией.
getElementsByTagName - получить узел по имени
attributes.getNamedItem("Дата").value  - значение атрибута
8 Ёпрст
 
гуру
10.03.10
09:22
(5) смотри что тут в отладчике
>>>Если Найти(прм_ОжидаемыеТеги,xml_ИмяТега)=0 Тогда

чему равно прм_ОжидаемыеТеги и xml_ИмяТега
9 1Сергей
 
10.03.10
09:24
У меня в карточке есть ссылка на инфостарт. Там есть сравниловка двух хмл-ок, посмотри в качестве примера
10 ko_elena
 
10.03.10
09:29
Добрый день!
Очень интересует эта тема. Так как надо будет разбирать дакомент такой же структуры.
11 Гость2
 
10.03.10
09:30
Процедура ЗагрузитьФайл(ТЗЗагрДок, ИмяФайла)

   ДокXML = гXMLАнализатор.СоздатьДокумент();
   ДокXML.Загрузить(ИмяФайла);
   Выборка = ДокXML.ЭлементДокумента.ПолучитьПодчиненныйПоНомеру(1);
   Выборка = Выборка.ВыбратьУзлы("Документ");
   СзУзлов = СоздатьОбъект("СписокЗначений");
   Для Сч = 0 По Выборка.КоличествоУзлов - 1 Цикл
       Элемент = Выборка.ПолучитьУзел(Сч);
       Вид = Элемент.ПолучитьАтрибут ("Вид");
       НомерДок = Элемент.ПолучитьАтрибут ("НомерДок");
       Стр = "";
       Если ТЗЗагрДок.НайтиЗначение(НомерДок, Стр, "НомерДок") = 0 Тогда
           Продолжить;
       КонецЕсли;
       
       СзУзлов.УдалитьВсе();
       СчЦ = 0;
       Для СчЦ = 1 По Элемент.КоличествоПодчиненных() Цикл
           СзУзлов.Установить(Элемент.ПолучитьПодчиненныйПоНомеру(СчЦ).Наименование,
                               Элемент.ПолучитьПодчиненныйПоНомеру(СчЦ));
       КонецЦикла;
       Если Вид = "Счет" Тогда
           ЗагрузитьСчет(СзУзлов);
       КонецЕсли;
   КонецЦикла;
КонецПроцедуры // ЗагрузитьФайл()
12 Гость2
 
10.03.10
09:32
+(11) Файл такого вида.

 <?xml version="1.0" encoding="windows-1251" standalone="no" ?>
- <ФайлОбмена ВерсияФормата="1.0" ИдКонфигурацииПриемника="Управление платежами 7.70.1.01" ДатаНачала="2009-10-01" ДатаОкончания="2009-11-15">
- <Документы>
- <Документ Вид="Счет" НомерДок="0010000001" ДатаДок="2009-10-16" Подразделение="001" Контрагент="400000020011" НПП="1">
 <НомерДок>0010000001</НомерДок>
 <ДатаДок>2009-10-16</ДатаДок>
13 ko_elena
 
10.03.10
09:38
Спасибо! сейчас будем пробывать!
14 1Сергей
 
10.03.10
09:40
(13) Семён Семёныч?
15 Блондинистая Ромашка
 
10.03.10
10:22
(11)
Почему-то у меня сообщает 0 узлов :( ну и дальше в цикл естественно не заходит :(

   ДокXML = гXMLАнализатор.СоздатьДокумент();
   ДокXML.Загрузить("c:\1c files\ВыгрузкаДоков.xml");  
   Выборка = ДокXML.ЭлементДокумента.ПолучитьПодчиненныйПоНомеру(1);
   Выборка = Выборка.ВыбратьУзлы("Document");
   СзУзлов = СоздатьОбъект("СписокЗначений");
   
   Сообщить(Выборка.КоличествоУзлов);

в чем ошибка? (мой файл xml выше, в первом посте)
16 Блондинистая Ромашка
 
10.03.10
10:36
Ура! Наконец-то доперло)))

   Для i=1 По ДокXML.ЭлементДокумента.КоличествоПодчиненных() Цикл
       ТекУзел = ДокXML.ЭлементДокумента.ПолучитьПодчиненныйПоНомеру(i);
       Вид = ТекУзел.ПолучитьАтрибут ("Vid");
       НомерДок = ТекУзел.ПолучитьАтрибут ("number");  
       Сообщить(Вид+"    "+НомерДок);
       //Сообщить(ТекУзел.КоличествоПодчиненных());
       
       Для j=1 По ТекУзел.КоличествоПодчиненных() Цикл
           ТекПодчиненныйУзел = ТекУзел.ПолучитьПодчиненныйПоНомеру(j);
           КодНоменклатуры = ТекПодчиненныйУзел.ПолучитьАтрибут ("nomenklatura");
           Сообщить(КодНоменклатуры);
       КонецЦикла;
       Сообщить("---");
   КонецЦикла;
17 ko_elena
 
10.03.10
15:36
Процедура Сформировать()
   
   Анализатор = СоздатьОбъект("AddIn.XMLParser");
   гДокДанных = Анализатор.СоздатьПоследовательноСчитываемыйДокумент();
   гДокДанных.СвязатьСФайлом(КаталогИБ()+"xml выгрузка\zayavka.xml");

       ТипТега = гДокДанных.Спуститься(); //корень
   ТипТега = гДокДанных.Спуститься(); // первый документ
   пока ТипТега=1 цикл
       
       //считываем шапку документа
       Сообщить("шапка");
       Эл = гДокДанных.СвойстваТекущегоУзла;
   
       
       КолАтр = Эл.КоличествоАтрибутов;
       Для й=1 по КолАтр Цикл
           Сообщить(Эл.ЗначениеАтрибута(й-1));
       КонецЦикла;                  
               
       ТипТега = гДокДанных.Спуститься();
       Пока ТипТега <> 3 Цикл
                       //считываем строки документа
           Эл = гДокДанных.СвойстваТекущегоУзла;
           Сообщить("строка");
           
           КолАтр = Эл.КоличествоАтрибутов;
           Для й=1 по КолАтр Цикл
               Сообщить(Эл.ЗначениеАтрибута(й-1));
           КонецЦикла;        
           ТипТега = гДокДанных.Следующий();
       КонецЦикла;    
       
       ТипТега = гДокДанных.Следующий();
       
   КонецЦикла;
КонецПроцедуры

методом проб и ошибок у меня заработало ВОТ В ТАКОМ ВИДЕ.
кто может прокомментировать?
потому как логика методов Спуститься() и Следующий() не понятна!!!
18 ko_elena
 
10.03.10
16:40
И еще один вопрос для спецов!
На что влияет способ выборки
СоздатьДокумент() и соответствующая обработка дальше
или
СоздатьПоследовательноСчитываемыйДокумент() и соответствующая обработка дальше

только на методы дальнейшей обработки или на скорость?
19 Гость2
 
10.03.10
20:01
(18) СоздатьПоследовательноСчитываемыйДокумент() - ты имеешь ЖЕСТСКУЮ структуру файла
СоздатьДокумент() - количество циклов (строчек) заранее неизвестно.
20 Злопчинский
 
11.03.10
04:14
(1) бяка..
//Ограничения на входящие файлы XML:                        
//1) В первой строке обязателен заголовок XML вида <?xml version="1.0" encoding="windows-1251"?>    .
//2) Каждый тег должен быть записан в отдельной строке. Возможны отступы от начала строки и пустые строки.
//3) Значения атрибутов - строго в двойных кавычках.
//4) Не поддерживаются текстовые значения (любые значения можно передавать только через атрибуты).    
//5) Комментарии и "подобные им" элементы XML не поддерживаются.
.
итого:
1. сплошь и рядом когда приходят файлы без заголовка, продавить на правильный формат - возможности нет
2. сплошь и рядом когда идет сплошняком
3. тут вроде все нормально обычно
4. по разному бывает...
5. по разному бывает.
.
итого, перед использованием (1) - его надо "нормализовать": проверить/вставить первую строку, распарсить теги на отдельные строки, проверить на соответсвие формату теги-атрибуты-значения-отсутствие комментов и ТОЛЬКО ПОТОМ применять (1).
21 Ёпрст
 
гуру
11.03.10
08:16
(20) зато быстро
22 Гость2
 
11.03.10
10:12
(16) А фотку?    :-)