Имя: Пароль:
1C
1С v8
простой разбор XML
0 MarinaProff
 
15.12.14
09:30
Привет всем, только начала работать с Xml, подскажите пожалуйста, есть файлик, в нем много текста и вот такой блог

<section ID="Full1CData">
                    <entry1C>
                        <Structure xmlns:d7p1="http://v8.1c.ru/8.1/data/core">;
                            <d7p1:Property name="Объект">
                                <d7p1:Value xsi:type="d7p1:Structure"/>
                            </d7p1:Property>
                            <d7p1:Property name="ФИО">
                                <d7p1:Value xsi:type="xs:string"> Иванов Иван Иванович</d7p1:Value>
                            </d7p1:Property>
                            <d7p1:Property name="Дата">
                                <d7p1:Value xsi:type="xs:dateTime">0001-01-01T00:00:00</d7p1:Value>
                            </d7p1:Property>
                            <d7p1:Property name="ДатаРождения">
                                <d7p1:Value xsi:type="xs:string"/>
                            </d7p1:Property>
                            <d7p1:Property name="Город">
                                <d7p1:Value xsi:type="xs:string"/>
                            </d7p1:Property>
</Structure>
                    </entry1C>
                </section>

Как мне вывести только
ФИО: Иванов ИВан Иванович
Дата: нужная дата
Город: нужный город и так далее...

Если пустой текст то не выводить (
1 Mankubus
 
15.12.14
09:57
чтениеXML.Прочитать()
2 su_mai
 
15.12.14
10:00
(0) Как мне вывести только...

Вам нужно прочитать данные их этого файла и вывести в отчет?
3 alexei366
 
15.12.14
10:27
А фотка то не своя!
4 MarinaProff
 
15.12.14
10:28
Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ПутьКФайлу);
    
    Пока Чтение.Прочитать() Цикл
        Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
            Если Чтение.Имя="section" Тогда
                Если Чтение.КоличествоАтрибутов() > 0 Тогда
                    Пока Чтение.ПрочитатьАтрибут() Цикл
                        Если Чтение.Имя="ID" Тогда
                            Если Чтение.Значение="Full1CData" Тогда
                                Пока Чтение.Прочитать() Цикл
                                    Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
                                        ИмяУзла = Чтение.Имя;
                                        Если СокрЛП(ИмяУзла) = "d7p1:Property" Тогда
                                            Если Чтение.КоличествоАтрибутов() > 0 Тогда
                                                Пока Чтение.ПрочитатьАтрибут() Цикл
                                                    Если Чтение.Имя="name" Тогда
                                                        НазваниеАтрибута=Чтение.Значение;
                                                    КонецЕсли;    
                                                КонецЦикла
                                            КонецЕсли
                                        КонецЕсли;
                                    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
                                        Текст=Чтение.Значение;
                                    ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
                                        Если ЗначениеЗаполнено(Текст) Тогда
                                            Сообщить(СТрока(НазваниеАтрибута)+": "+Строка(Текст));
                                            НазваниеАтрибута="";Текст="";
                                        КонецЕсли;
                                        Если Чтение.Имя="section" Тогда
                                        КонецЕсли;
                                    КонецЕсли;
                                КонецЦикла;
                            КонецЕсли;
                        КонецЕсли;
                    КонецЦикла;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
5 MarinaProff
 
15.12.14
10:28
Вроде работает, только не могу выйти из всех циклов при

Если Чтение.Имя="section" Тогда
Прервать;
КонецЕсли;
6 su_mai
 
15.12.14
10:29
(3) Google пишет:

"Скорее всего, на картинке  прокурор крыма наталья поклонская"

Так что по оккуратнее :)
7 DrZombi
 
гуру
15.12.14
10:30
(0) Начни с вики wiki:XML
8 rasswet
 
15.12.14
10:31
ПостроительDOM не плохо читает
9 DrZombi
 
гуру
15.12.14
10:31
(6) Марина, Марин? И фото не её (его)? :)
10 su_mai
 
15.12.14
10:32
(0) Да ладно используй XPath, и не майся.
11 MarinaProff
 
15.12.14
10:36
(6) (9)  а я ее даже не узнала ((
12 Mankubus
 
15.12.14
10:38
(3) расходимся
13 su_mai
 
15.12.14
10:39
(12) А мы пока еще и не сходились :)
14 Котокот
 
15.12.14
10:41
"в нем много текста и вот такой блог "
А где ссылка на блог?
15 MarinaProff
 
15.12.14
10:43
а зачем весь текст то ? 6367 символа 162 строки, мне вытянуть надо только из <section ID="Full1CData">
16 MarinaProff
 
15.12.14
10:44
(4) Этот код работает, только мне надо при

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


Закончить все циклы
17 su_mai
 
15.12.14
10:44
(14) Глаза то раскрой, написано же

http://v8.1c.ru/8.1/data/core">"; target="_blank" rel="nofollow" class="extralink">http://v8.1c.ru/8.1/data/core";

ваще :)
18 su_mai
 
15.12.14
10:45
(16) Возврат напиши
19 Александр_
Тверь
 
15.12.14
10:45
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяВыходногоФайла);

ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);


в данном случае ОбъектXDTO нечто очень похожее на структуру будет. С которой очень легко работать.
20 Александр_
Тверь
 
15.12.14
10:47
а (4) это жесть...
21 alexei366
 
15.12.14
10:56
(19) (20)  Вот мужик дело говорит.
Вот те ссылка http://infostart.ru/public/311011/ почитай.
И помни в след раз не будем помогать без фотки)
22 Котокот
 
15.12.14
10:57
(17) Ой, точно!
23 MarinaProff
 
15.12.14
11:02
Спасибо ребят
24 IVT_2009
 
15.12.14
12:05
Спасибо! Про XDTO как то руки не доходили. Скорость мне понравилась
25 su_mai
 
15.12.14
13:00
(10) XPath запрос:

/section[@ID='Full1CData']/entry1C/Structure//*

выдает:

d7p1:Property name="Объект"
d7p1:Value xsi:type="d7p1:Structure"
d7p1:Property name="ФИО"
d7p1:Value  Иванов Иван Иванович
d7p1:Property name="Дата"
d7p1:Value 0001-01-01T00:00:00
d7p1:Property name="ДатаРождения"
d7p1:Value xsi:type="xs:string"
d7p1:Property name="Город"
d7p1:Value xsi:type="xs:string"

Перебирая результат можно прочитать все структуры начиная новую с узла "Объект"

Хотя если схема известна, то можно и XDTO помучить.
26 MarinaProff
 
15.12.14
13:05
DOMПостроитель =  Новый ПостроительDOM() ;
                    ЧтениеXML = Новый ЧтениеXML;
                    ЧтениеXML.УстановитьСтроку(XML_);
                    DOMДокумент = DOMПостроитель.Прочитать(ЧтениеXML);
                    РазыменовательПИ = DOMДокумент.СоздатьРазыменовательПИ(DOMДокумент);
                    ТекстЗапросаXPath =
                            "/section[@ID='Full1CData']/entry1C/Structure//*"

                    ;
                    XPathЗапрос = DOMДокумент.СоздатьВыражениеXPath(
                                        ТекстЗапросаXPath, РазыменовательПИ);
                    РезультатЗапросаXPath = XPathЗапрос.Вычислить(DOMДокумент);
                    
                    ЭлементDOM = РезультатЗапросаXPath.ПолучитьСледующий();
                    Если ЭлементDOM <> Неопределено Тогда
                        
                    КонецЕсли;
27 MarinaProff
 
15.12.14
13:05
Я шел через этот ход, у меня все время ЭлементDOM неопределено
28 sapphire
 
15.12.14
13:12
(27) хм.. с таким ником в мужсом роде.. фу..
29 sapphire
 
15.12.14
13:15
(26) ТекстЗапросаXPath неверный.
30 sapphire
 
15.12.14
13:20
в (0) :
<Structure xmlns:d7p1="http://v8.1c.ru/8.1/data/core">"; target="_blank" rel="nofollow" class="extralink">http://v8.1c.ru/8.1/data/core">;;

приведет к ошибке разбора XML
31 su_mai
 
15.12.14
13:27
(29) (30) Обычно "джентельмены" приводят верный :)
32 su_mai
 
15.12.14
13:27
+(31) В таких случаях
33 sapphire
 
15.12.14
13:28
(31) в (25) ошибка
34 su_mai
 
15.12.14
13:34
(31) -> (31)
35 MarinaProff
 
15.12.14
14:02
//*[@ID="Full1CData"]/*/*/*

Результат:

<d7p1:Property name="&#x41E;&#x431;&#x44A;&#x435;&#x43A;&#x442;">
<d7p1:Value xsi:type="d7p1:Structure"/>
</d7p1:Property>
-----------------------
<d7p1:Property name="&#x412;&#x440;&#x430;&#x447;">
<d7p1:Value xsi:type="xs:string"/>
</d7p1:Property>
-----------------------
<d7p1:Property name="&#x414;&#x430;&#x442;&#x430;">
<d7p1:Value xsi:type="xs:dateTime">0001-01-01T00:00:00</d7p1:Value>
</d7p1:Property>
36 sapphire
 
15.12.14
14:09
(35) Зачем так сурово использовать java для проверки шаблона XPath :)))))
37 MarinaProff
 
15.12.14
14:24
Вроде взлетело

Если ЗначениеЗаполнено(XML_) Тогда
                
                    DOMПостроитель =  Новый ПостроительDOM() ;
                    ЧтениеXML = Новый ЧтениеXML;
                    ЧтениеXML.УстановитьСтроку(XML_);
                    DOMДокумент = DOMПостроитель.Прочитать(ЧтениеXML);
                    РазыменовательПИ = DOMДокумент.СоздатьРазыменовательПИ(DOMДокумент);
                    ТекстЗапросаXPath =
                        "//*[@ID=""Full1CData""]/*/*/*"

                    ;
                    XPathЗапрос = DOMДокумент.СоздатьВыражениеXPath(
                                        ТекстЗапросаXPath, РазыменовательПИ);
                    РезультатЗапросаXPath = XPathЗапрос.Вычислить(DOMДокумент,);
                    ЭлементDOM = РезультатЗапросаXPath.ПолучитьСледующий();
                    Пока ЭлементDOM <> Неопределено Цикл
                        Название=ЭлементDOM.Атрибуты.ПолучитьИменованныйЭлемент("name").Значение;    
                        Текст=ЭлементDOM.ТекстовоеСодержимое;
                        Если ЗначениеЗаполнено(Название) И ЗначениеЗаполнено(Текст) Тогда
                        Сообщить(Название+": "+Текст);
                        КонецЕсли;
                        ЭлементDOM = РезультатЗапросаXPath.ПолучитьСледующий();
                    КонецЦикла;


КонецЕсли;



Что посоветуете?
38 sapphire
 
15.12.14
14:53
ОчиститьСообщения();
ОчиститьСообщения();
XML_="<section ID=""Full1CData"">
|                    <entry1C>
|                        <Structure xmlns:d7p1=""http://v8.1c.ru/8.1/data/core""; xmlns:xs=""http://www.w3.org/2001/XMLSchema""; xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""; xsi:type=""Structure"">

|                            <d7p1:Property name=""Объект"">
|                                <d7p1:Value xsi:type=""d7p1:Structure""/>
|                            </d7p1:Property>
|                            <d7p1:Property name=""ФИО"">
|                                <d7p1:Value xsi:type=""xs:string""> Иванов Иван Иванович</d7p1:Value>
|                            </d7p1:Property>
|                            <d7p1:Property name=""Дата"">
|                                <d7p1:Value xsi:type=""xs:dateTime"">0001-01-01T00:00:00</d7p1:Value>
|                            </d7p1:Property>
|                            <d7p1:Property name=""ДатаРождения"">
|                                <d7p1:Value xsi:type=""xs:string""/>
|                            </d7p1:Property>
|                            <d7p1:Property name=""Город"">
|                                <d7p1:Value xsi:type=""xs:string""/>
|                            </d7p1:Property>
|                    </Structure>
|             </entry1C>
|</section>";
DOMПостроитель =  New COMObject("Msxml2.DOMDocument");

DOMПостроитель.loadXML(XML_);
ТекстЗапросаXPath ="/section[@ID='Full1CData']/entry1C/*";
ЭлементDOM = DOMПостроитель.SelectSingleNode(ТекстЗапросаXPath);
ЗначXML=ЭлементDOM.XML;
ЗначXML=СтрЗаменить(ЗначXML,":d7p1","");
ЗначXML=СтрЗаменить(ЗначXML,"d7p1:","");


ЧтениеXML=Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ЗначXML);
Сериализатор=Новый СериализаторXDTO(ФабрикаXDTO);
ПолученноеЗначение=Сериализатор.ПрочитатьXML(ЧтениеXML);
Для Каждого КлючИЗначение Из ПолученноеЗначение Цикл
    Сообщить(""+КлючИЗначение.Ключ+"="+КлючИЗначение.Значение);
КонецЦикла;
39 su_mai
 
15.12.14
15:10
(38) ЗначXML=СтрЗаменить(ЗначXML,":d7p1","");
ЗначXML=СтрЗаменить(ЗначXML,"d7p1:","");

вот она вся мощь 1С :)
40 sapphire
 
15.12.14
16:31
(39) Скорее лень :)
А изменять namеspace тоже неохота, хотя это одна строка :)
41 Garykom
 
гуру
15.12.14
16:36
Хоть бы один предложил вместо парсинга XML вытащить данные попроще...методом regexp или даже через поиск в цикле ))
42 su_mai
 
15.12.14
16:41
(41) Про regexp даже не говори :). Его же нет в платформе. :)

(40) Приведенное xpath выражение (25) прекрасно работает в Altowa XML Spy. Это я к тому, что технически (на уровне платформы) возможно сделать так что бы совсем без "геммороя" все было.
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn