Имя: Пароль:
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. Это я к тому, что технически (на уровне платформы) возможно сделать так что бы совсем без "геммороя" все было.