Имя: Пароль:
1C
1С v8
Как парсить XML или отсутствие логики не запрещает программировать.
0 karpos
 
04.02.14
09:01
Ребята подскажите обработку пишу 1с 8.2 работа с XML. С XML первый раз связался.Вот что содержит файл XML

<Товар>
<>Наименование<>
<>Ед.изм</>
<>Количество</>
<>Сумма</>
</Товар>
Товаров понятно многою. Но я не могу понять как мене туда провалиться

Файл = Новый ЧтениеXML;
    Файл.ОткрытьФайл("d:\1.xml");
    Пока Файл.Прочитать() Цикл
      Если Файл.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
        Если Файл.Имя = "Товар" Тогда
          Пока Файл.ПрочитатьАтрибут() Цикл
            Сообщить(Файл.Имя);
          КонецЦикла;
         КонецЕсли;    
        КонецЕсли;    
    КонецЦикла;
    
Файл.Закрыть();

В Сообщить я хочу вывести Сумму, Количество, Наименование, в общем хочу чтоб он туда провалился.
1 Рэйв
 
04.02.14
09:02
структура прикольная:-)
2 karpos
 
04.02.14
09:04
<Товар>
<Наименование>Апельсин</Наименование>
<Eд.изм>1</Ед.изм>
<Количество>10</Количество>
<Сумма>50</Сумма>
</Товар>

Вот что содержит) а в верху не верно)
3 Рэйв
 
04.02.14
09:04
(0)этот файл xml сам делал?
4 Рэйв
 
04.02.14
09:04
ааа :-)
5 karpos
 
04.02.14
09:04
Вот Рэйв шустрый какой)
6 Рэйв
 
04.02.14
09:06
Как можно загрузить XML документ произвольной структуры?
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлу);

Пока Чтение.Прочитать() Цикл

    // Прочитать "структурные части" элементов.
    // Проверить, какая часть элемента - текущая.
    Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
        ИмяУзла = Чтение.Имя; Сообщить("--" + ИмяУзла);

        // Атрибуты элементов можно читать только если текущая часть -
        // начало элемента
        Пока Чтение.ПрочитатьАтрибут() Цикл

            // Прочитать данные узла атрибута.
            ТипУзла = Чтение.ТипУзла;
            Имя = Чтение.Имя;
            Значение = Чтение.Значение;

            // Обработать полученные значения.

        КонецЦикла;

    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда

        // В примере просто выводим текст в окно сообщений.
        Сообщить("Текст:" + Чтение.Значение);

    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда

        // В примере просто выводим признак конца элемента
        // в окно сообщений Сообщить("--Конец:" + Чтение.Имя);

    КонецЕсли;

КонецЦикла;
(С)Габец
7 butterbean
 
04.02.14
09:17
(0) у тебя нет атрибутов, только вложенные узлы "Наименование", "ЕИ" и т.п.
8 karpos
 
04.02.14
11:49
что то не работает, лыжи не едут.

        Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл("d:\1.xml");
    
    Пока Чтение.Прочитать() Цикл    
        Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            Если Чтение.Имя = "Товар" Тогда
            ИмяУзла = Чтение.Имя; Сообщить("--" + ИмяУзла);
                Пока Чтение.ПрочитатьАтрибут() Цикл
                    //ТипУзла = Чтение.ТипУзла;
                                    Имя = Чтение.Имя;
                    Сообщить(Имя);
                    //Значение = Чтение.Значение;  
                КонецЦикла;
            ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
                Сообщить("Текст:" + Чтение.Значение);     
            КонецЕсли;
        КонецЕсли;    
    КонецЦикла;
    
    Чтение.Закрыть();

я приводил XML выше это условие (Если Чтение.Имя = "Товар" Тогда ) потому что есть позиций не товар услуга в XML
и я не могу провалить в товар и  вывести все поля от туда, Сообщить(Имя); он выводит товар(просто слово товар).
9 hhhh
 
04.02.14
11:54
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента ??? Тогда
            Если Чтение.Имя = "Товар" Тогда
  
            ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст ????  Тогда

что курил?
10 Serginio1
 
04.02.14
11:55
11 Господин ПЖ
 
04.02.14
11:55
<Товар>
<>Наименование<>
<>Ед.изм</>
<>Количество</>
<>Сумма</>
</Товар>

так верстают .удаки...
12 karpos
 
04.02.14
12:00
да не то это  Господин ПЖ
13 Господин ПЖ
 
04.02.14
12:10
(12) напихивать атрибуты в узлы - так альтернативноодарнные делают... иди метро водить

(7) +1
14 karpos
 
04.02.14
12:20
Господин ПЖ, после того как я написал в верху я написал что ошибся и написал ниже.

<Товар>
<Наименование>Апельсин</Наименование>
<Eд.изм>1</Ед.изм>
<Количество>10</Количество>
<Сумма>50</Сумма>
</Товар>
15 Зойч
 
04.02.14
12:21
Юзай XDTO
16 Господин ПЖ
 
04.02.14
12:33
(14) нормальный xml выглядит примерно так:

<?xml version="1.0" encoding="windows-1251"?>
<Товары>
<Товар Eд.изм="1" Количество="10" Сумма ="50">"Апельсин"</Товар>
</Товары>

а что там у вас - это адЪ и израиль
17 Asmody
 
04.02.14
12:35
(16) какая принципиальная половая разница записи данных в атрибуты или узлы? ну, кроме, понятно, увеличения размера xml
18 Asmody
 
04.02.14
12:36
я не уверен, но вроде "Ед.изм" это не совсем корректное имя в xml, не?
19 Господин ПЖ
 
04.02.14
12:38
(18) не помню я - это надо форматы смотреть... это уже мелочи... хотя конечно я за слитные имена в латинице
20 Господин ПЖ
 
04.02.14
12:40
(17) выборки по разному будут организованы

то что у него есть в (8) заточено как раз на чтение атрибутов
21 karpos
 
04.02.14
12:40
у меня так

?xml version="1.0" encoding="windows-1251"?>
<Товары>
  <Код>111111</Код>
  <Наименование>Апельсин</>
  <Ед.изм>шт</Ед.изм>
  <Количестов>10<Количестов>
</Товары>
22 karpos
 
04.02.14
12:40
пропутил закрывающий тег
23 Asmody
 
04.02.14
12:43
(19) пишут, что можно http://www.w3.org/TR/xml/#sec-common-syn
24 Господин ПЖ
 
04.02.14
12:45
(21) клева... у тебя 4 товара... "код", "наименование", "ед. изм" и "количество"
25 Рэйв
 
04.02.14
12:54
(21)Ты свой файл хотябы в IE попробуй напрямую открыть. Если там пошлет, то значит файл впринципе не читаемый как xml
26 Asmody
 
04.02.14
12:54
(21) нет, сначала нужен узел <Товары> - список товаров, который содержит узлы <Товар>, каждый из которых содержит структуру описания товара
27 karpos
 
04.02.14
12:56
я не пойму вас  Господин ПЖ, такая xml вы не верите ?

<Товары>
  <Код>111111</Код>
  <Наименование>Апельсин</>
  <Ед.изм>шт</Ед.изм>
  <Количестов>10<Количестов>
</Товары>
<Товары>
  <Код>111112</Код>
  <Наименование>Груша</>
  <Ед.изм>шт</Ед.изм>
  <Количестов>2<Количестов>
</Товары>
<Услуга>
  <Код>111113</Код>
  <Наименование>ХранениеФрутов</>
  <Ед.изм>дни</Ед.изм>
  <Количестов>1<Количестов>
</Услуга>
28 Рэйв
 
04.02.14
12:57
(27)Жесть.Жестяная
:-)
29 Рэйв
 
04.02.14
12:58
хотя впринципе  пойдет, хот и необычно
30 karpos
 
04.02.14
13:03
да и мне надо вытащить что внутри товаров.
31 Господин ПЖ
 
04.02.14
13:03
(27) такой xml не валиден... нет заголовка и корневого узла
32 karpos
 
04.02.14
13:03
это я Рэйв говорю) а так да жесть)
33 Господин ПЖ
 
04.02.14
13:04
убей себя уже об стену... есть форматы - Асмоди уже давал ссылку, а то что ты лепишь это куита на палке, а не xml...
34 karpos
 
04.02.14
13:06
что ты за приставучий такой ГосподинПД
<Заголовок>
<Товары>
  <Код>111111</Код>
  <Наименование>Апельсин</>
  <Ед.изм>шт</Ед.изм>
  <Количестов>10<Количестов>
</Товары>
<Товары>
  <Код>111112</Код>
  <Наименование>Груша</>
  <Ед.изм>шт</Ед.изм>
  <Количестов>2<Количестов>
</Товары>
<Услуга>
  <Код>111113</Код>
  <Наименование>ХранениеФрутов</>
  <Ед.изм>дни</Ед.изм>
  <Количестов>1<Количестов>
</Услуга>
</Заголовок>

ты не Господин ПЖ, ты XML валидор ))))
35 Рэйв
 
04.02.14
13:07
(34)просто так открывается в интернет эксплорере?
36 karpos
 
04.02.14
13:07
нормальная эта XML Вот сейчас точно как у меня в файле я просто некоторые поля поменял так не хочу видели что за задание конкретно. А суть я уже всю описал
37 karpos
 
04.02.14
13:07
да
38 Рэйв
 
04.02.14
13:16
вот так читается твой файл
39 Рэйв
 
04.02.14
13:16
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(Путь);

Пока Чтение.Прочитать() Цикл

    Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
        ИмяУзла = Чтение.Имя;
        Сообщить("--" + ИмяУзла);
    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
        Сообщить("      значение:" + Чтение.Значение);
    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
        Сообщить("--/" + Чтение.Имя);
    КонецЕсли;

КонецЦикла;
40 karpos
 
04.02.14
13:19
Рэйв я не пробовал выполнять в уме прокрутил  (ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда ) будет выполняться везде где текст значит и где услуга тоже выполнится.
41 Рэйв
 
04.02.14
13:20
(40)Так что тебе надо то?
42 Рэйв
 
04.02.14
13:20
только товары чтоли?
43 karpos
 
04.02.14
13:21
Да нужно парсить только товары, только не сами товары а что внутри товаров.
44 karpos
 
04.02.14
13:22
А услуги и то что в услугах не нужно мне
45 Рэйв
 
04.02.14
13:27
(44)Так пропускай и не парси
46 karpos
 
04.02.14
13:28
Так вот и сижу мучу такой код,пока не получается
47 Рэйв
 
04.02.14
13:32
(46)Ты бы не парил себе мозг, прочитал все полностью в ТЗ или дерево, а потом уже разобрался где товар, а где услуга
48 Рэйв
 
04.02.14
13:34
А перскакивать через корни тегов - зело хлопотно
49 sapphire
 
04.02.14
13:37
(16) ИМХО, это ненормальный XML :)
<?xml version="1.0" encoding="windows-1251"?>
<Товары>
<Строка Товар="Апельсин" Eд.изм="1" Количество="10" Сумма ="50"/>
</Товары>
50 sapphire
 
04.02.14
13:38
(18) Канешна
51 karpos
 
04.02.14
14:54
я тут тупил как мне кажется )

Пока Чтение.Прочитать() Цикл
        Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            Если Чтение.Имя = "Найменование" Тогда
                Сообщить(Чтение.Имя);
            КонецЕсли;
            
            Если Чтение.Имя = "Количество" Тогда
                Сообщить(Чтение.Имя);
            КонецЕсли;        
            
            Если Чтение.Имя = "Сумма" Тогда
                Сообщить(Чтение.Имя);
            КонецЕсли;        
         КонецЕсли;

     КонецЦикла;

Смотрите ему все равно на дерево он выводит Код столько раз сколько его с XML то есть я могу просто обозначить поля которые мне нужно вывести, но вот не задача Чтение.Значение не выводит ничего а я как понимаю <Код>111113</Код> точто между тегами это и есть же значение .???
52 ilyavorobyev
 
04.02.14
15:01
Вот xml

<?xml version="1.0" encoding="UTF-8"?>
<ДоговорыКонтрагентов>
    <Документ>
        <Номер>000000189</Номер>
        <Наименование>Документ1</Наименование>
        <Дата>08.09.2011 17:24:00</Дата>
        <ПутьКФайлу>R:\Файл.doc</ПутьКФайлу>
    </Документ>
</ДоговорыКонтрагентов>

Вот код который считывает
    Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ПутьКФайлу);
    Пока Чтение.Прочитать() Цикл
        // Прочитать "структурные части" элементов.
        // Проверить, какая часть элемента - текущая.
        Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда

            ИмяУзла = Чтение.Имя;
            Если СокрЛП(ИмяУзла) = "Документ" Тогда
                НоваяСтрока = ТаблицаЗначенийВыгруз.Добавить();
                Индекс = Индекс + 1;
            КонецЕсли;

        ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
            Если ИмяУзла = "Номер" Тогда
                НоваяСтрока.Номер = Строка(Число(Чтение.Значение));
            КонецЕсли;
            Если ИмяУзла = "Дата" Тогда
                НоваяСтрока.Дата = Дата(Чтение.Значение);        
            КонецЕсли;
            Если ИмяУзла = "ПутьКФайлу" Тогда
                Попытка
                    Файл = Новый Файл(Чтение.Значение);
                    Если НЕ Файл.Существует() Тогда
                        Строка = ТаблицаЗначенийВыгруз.НайтиПоИдентификатору(НоваяСтрока.ПолучитьИдентификатор());
                        ТаблицаЗначенийВыгруз.Удалить(Строка);    
                    Иначе
                        НоваяСтрока.Путь = СокрЛП(Чтение.Значение);
                    КонецЕсли;
                Исключение
                    Сообщить("Файл не найден: " + СокрЛП(Чтение.Значение));
                КонецПопытки;        
            КонецЕсли;
        ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            // В примере просто выводим признак конца элемента
            // в окно сообщений
            //Сообщить("--Конец:" + Чтение.Имя);

        КонецЕсли;
    КонецЦикла;
53 Serginio1
 
04.02.14
15:11
(51) Ты использовао (10)?
54 karpos
 
04.02.14
15:13
ИмяУзла = Чтение.Имя;
            Если СокрЛП(ИмяУзла) = "Документ" Тогда
                НоваяСтрока = ТаблицаЗначенийВыгруз.Добавить();
                Индекс = Индекс + 1;
            КонецЕсли;

Зачем этот код?
55 karpos
 
04.02.14
15:23
ilyavorobyev,понял ты документ тоже загоняешь туда а потом что внутри
56 ilyavorobyev
 
04.02.14
16:07
(55) я просто в таблицу значений все грузил и когда новый документ то создавал  новую строку)
57 ilyavorobyev
 
04.02.14
16:08
(55) а индекс чтобы потом удалить эту строку можно было
58 alexei366
 
04.02.14
16:18
ЖЕСТЬ)))) Делай через ФабрикуXDTO, там и бегать по документу в разы удобней и типы значений будут (а то ща где у типа число получаешь строку и приводишь)
59 alexei366
 
04.02.14
16:20
(58) Через ЧтениеXML оно конешь быстрее (дерево не строиться и не загоняется в оперативу), но я так подозреваю этот кусок кода запускаться будет в лучшем случае раз в день
60 ilyavorobyev
 
04.02.14
16:25
(59) Что вам не нравится? я писал для своих нужд и все ок, и кстати надо отдать должное он быстро парсит
61 Зойч
 
04.02.14
16:32
(60) зачем ты изобретал очередной велосипед???
62 karpos
 
04.02.14
16:54
ну кидайте примерчики )))
63 ilyavorobyev
 
04.02.14
17:00
(61) Кому как, мне он показался не сложным, тем более фабрикуxtdo можно в обработке сделтаь?
64 DS
 
04.02.14
17:27
Фабрику? Уж лучше DOM.
65 Serginio1
 
04.02.14
17:45
(64) Через фабрику проще записывать и читать.
DOM вещь хорошая, но она универсальна.

Через фабрику читаешь последовательно, а не берешь сразу весь текст

ЧтениеXML=Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайла);
ЧтениеXML.ПерейтиКСодержимому();
  
ЧтениеXML.Прочитать();
Сч=0;

Пока ЧтениеXML.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл


ОбъектXDTO=ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя));
Сч=Сч+1;
Если Сч%100=0 Тогда
    состояние("Загружено "+сч+" объектов");
КонецЕсли;    
КонецЦикла;

ЧтениеXML.Закрыть();
66 karpos
 
04.02.14
17:48
ilyavorobyev, тебе огромное спасибо но не мог бы ты необъяснимость немного кое что еще.

так работает
Пока Чтение.Прочитать() Цикл
    Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
        ИмяУзла = Чтение.Имя;
        Если СокрЛП(ИмяУзла) = "Товар" Тогда
            Индекс = Индекс + 1;
        КонецЕсли;    
    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
           Если ИмяУзла = "Код" Тогда
                Сообщить(Строка(Чтение.Значение));
       КонецЕсли;
    КонецЕсли;    
КонецЦикла;

если же делаю так

Пока Чтение.Прочитать() Цикл
    //Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
    //    ИмяУзла = Чтение.Имя;
    //    Если СокрЛП(ИмяУзла) = "Товар" Тогда
    //        Индекс = Индекс + 1;
    //    КонецЕсли;    
    Если Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
           Если Чтение.Имя = "Код" Тогда //имя ула меняем на чтение имя там же должно быть тоже значение
                Сообщить(Строка(Чтение.Значение));
       КонецЕсли;
    КонецЕсли;    
КонецЦикла;

то не работает я вот пишу и думаю что то что я коментарил нужно для обпределения именно НачалоЭлемента имени элемента а так он наверное не может понять начало или конец.
67 ilyavorobyev
 
04.02.14
18:06
попробуй так
Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ПутьКФайлу);
    Пока Чтение.Прочитать() Цикл
        // Прочитать "структурные части" элементов.
        // Проверить, какая часть элемента - текущая.
        Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда

            ИмяУзла = Чтение.Имя;
            Если СокрЛП(ИмяУзла) = "Товар" Тогда
                Сообщить("Товар Новый");
            КонецЕсли;

        ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
            Если ИмяУзла = "Наименование" Тогда
                Сообщить("Наименование " + Чтение.Значение);
            КонецЕсли;
            Если ИмяУзла = "Eд.изм" Тогда
                Сообщить("Eд.изм " + Чтение.Значение);        
            КонецЕсли;
            Если ИмяУзла = "Количество" Тогда
                Сообщить("Количество " + Чтение.Значение);        
            КонецЕсли;
            Если ИмяУзла = "Сумма" Тогда
                Сообщить("Сумма " + Чтение.Значение);        
            КонецЕсли;
        ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            // В примере просто выводим признак конца элемента
            // в окно сообщений
            //Сообщить("--Конец:" + Чтение.Имя);

        КонецЕсли;
    КонецЦикла;