Загрузка xml с помощью XDTO.

1. zaxarovsky 111 03.10.13 16:20 Сейчас в теме
Добрый день!
Есть файлик xml
<AxaptaXMLExport xmlns:Table="urn:www.navision.com/Formats/Table" version="1.0">
	<transaction version="1.0">
		<Table:Record name="InventTableExportDC" row="1">
			<Table:Field name="ItemId">00099B101</Table:Field>
			<Table:Field name="FactoryId_OK">Остальные</Table:Field>
			<Table:Field name="FactoryItemId">ББ00017-55555</Table:Field>
			<Table:Field name="itemName">ШОКОЛАД_Бабаевский_горький_111111111111</Tab­le:Field>
			<Table:Field name="NetWeight">5.120</Table:Field>
			<Table:Field name="Quantity">200.00</Table:Field>
			<Table:Field name="UnitId">шт</Table:Field>
			<Table:Field name="UnitVolume"/>
			<Table:Field name="grossDepth">387.00</Table:Field>
			<Table:Field name="grossHeight">82.00</Table:Field>
			<Table:Field name="grossWidth">282.00</Table:Field>
			<Table:Field name="standardPalletQuantity">800.00</Table:Field>
			<Table:Field name="QtyPerLayer">8.00</Table:Field>
			<Table:Field name="ABCRevenue"/>
			<Table:Field name="Price">0</Table:Field>
			<Table:Field name="applicationtime_OK">365</Table:Field>
			<Table:Field name="FactoryNE">ББ00017B101</Table:Field>
			<Table:Field name="standardShowBoxQuantity">50.00</Table:Field>
		</Table:Record>
	</transaction>
</AxaptaXMLExport>
Показать


Генерирую по нему схему xsd при помощи проги Oxygen XML.
Получаю 2 файлика:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:www.navision.com/Formats" elementFormDefault="qualified" xmlns:Table="urn:www.navision.com/Formats/Table">
  <xs:import namespace="urn:www.navision.com/Formats/Table" schemaLocation="Table.xsd"/>
  <xs:element name="AxaptaXMLExport">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="transaction"/>
      </xs:sequence>
      <xs:attribute name="version" use="required" type="xs:decimal"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="transaction">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="Table:Record"/>
      </xs:sequence>
      <xs:attribute name="version" use="required" type="xs:decimal"/>
    </xs:complexType>
  </xs:element>
</xs:schema>
Показать

И
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:www.navision.com/Formats/Table" xmlns:Table="urn:www.navision.com/Formats/Table">
  <xs:import schemaLocation="InventTable_19092013.xsd"/>
  <xs:element name="Record">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="Table:Field"/>
      </xs:sequence>
      <xs:attribute name="name" use="required" type="xs:NCName"/>
      <xs:attribute name="row" use="required" type="xs:integer"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Field" >
    <xs:complexType mixed="true">

      <xs:attribute name="name" use="required" type="xs:NCName"/>

    </xs:complexType>
  </xs:element>
</xs:schema>
Показать


Импортирую в дерево метаданных конфы как Пакет XDTO.
После этого вот таким кодом пытаюсь загрузить исходный xml-файл

	Схемы = Новый Массив;
	Схемы.Добавить("C:\Темр\схема1.xsd");
	Схемы.Добавить("C:\Темр\схема2.xsd");
	Пакеты = Новый Массив;
	П_1= ФабрикаXDTO.Пакеты.Получить("urn:www.navision.com/Formats");
	П_2= ФабрикаXDTO.Пакеты.Получить("urn:www.navision.com/Formats/Table");

	Пакеты.Добавить(П_1);
	Пакеты.Добавить(П_2);
	
	Фабрика = СоздатьФабрикуXDTO(Схемы, Пакеты);
	
	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл(ИмяФайла);      
	ОбъектГлавный = Фабрика.ПрочитатьXML(ОбменXML);
	
	Для Каждого Объект1 Из ОбъектГлавный.transaction.Record Цикл
		ОбработкаПрерыванияПользователя();
		Для Каждого Объект2 Из Объект1.Field Цикл 
			Сообщить(Объект2);
                        //считывание текстового содержимого...  как?
		КонецЦикла;
	КонецЦикла;
	
    ФайлОбмена = "";
    ОбменXML.Закрыть();

Показать


Однако Объект2 типа ОбъектXDTO не содержит текстового содержимого. Там только атрибуты.
Как добраться до данных? Вразумите! :)
Спасибо.
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
22. kasper076 109 07.10.13 08:59 Сейчас в теме
Как вариант можно еще использовать xPath и/или xsl
Вот ссылка на цикл статей

	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл("D:\Новый1.xml");      
	ПостроительДОМ = Новый ПостроительDOM;
	ДокументДом = ПостроительДОМ.Прочитать(ОбменXML);
	Результат = ДокументДом.ВычислитьВыражениеXPath("/AxaptaXMLExport/transaction/Table:Record/Table:Field", ДокументДом, Новый РазыменовательПространствИменDOM(ДокументДом), ТипРезультатаDOMXPath.УпорядоченныйИтераторУзлов);
	Пока Истина Цикл
		Значение = Результат.ПолучитьСледующий();
		Если Значение = Неопределено Тогда
			Прервать;
		КонецЕсли;
		Сообщить(Значение.Атрибуты.ПолучитьИменованныйЭлемент("name").ЗначениеУзла + " = " + Значение.ТекстовоеСодержимое);
	КонецЦикла;	
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. zaxarovsky 111 03.10.13 16:23 Сейчас в теме
3. zaxarovsky 111 04.10.13 07:30 Сейчас в теме
Где-же, где советы-советики? Гуглить и курить не предлагать! :)
4. kasper076 109 04.10.13 09:35 Сейчас в теме
Схема1
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:www.navision.com/Formats" elementFormDefault="qualified" xmlns:Table="urn:www.navision.com/Formats/Table">
  <xs:import namespace="urn:www.navision.com/Formats/Table" schemaLocation="Схема2.xsd"/>
  <xs:element name="AxaptaXMLExport">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="transaction"/>
      </xs:sequence>
      <xs:attribute name="version" use="required" type="xs:decimal"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="transaction">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="Table:Record"/>
      </xs:sequence>
      <xs:attribute name="version" use="required" type="xs:decimal"/>
    </xs:complexType>
  </xs:element>
</xs:schema>
Показать

Схема2
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:www.navision.com/Formats/Table" xmlns:Table="urn:www.navision.com/Formats/Table">
  <xs:import schemaLocation="Схема1.xsd"/>
  <xs:element name="Record">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="Table:Field"/>
      </xs:sequence>
      <xs:attribute name="name" use="required" type="xs:NCName"/>
      <xs:attribute name="row" use="required" type="xs:integer"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Field" >
    <xs:complexType mixed="true">

      <xs:attribute name="name" use="required" type="xs:NCName"/>

    </xs:complexType>
  </xs:element>
</xs:schema>
Показать

Текст
	Схемы = Новый Массив;
	Схемы.Добавить("D:\схема1.xsd");
	Схемы.Добавить("D:\схема2.xsd");
	
	Фабрика = СоздатьФабрикуXDTO(Схемы);
	
	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл("D:\Новый1.xml");      
	ОбъектГлавный = Фабрика.ПрочитатьXML(ОбменXML);
	
	Для Каждого Объект1 Из ОбъектГлавный.transaction.Record.Field Цикл
		Сообщить(Объект1.name);
		//считывание текстового содержимого...  как?
	КонецЦикла;
	
	ФайлОбмена = "";
	ОбменXML.Закрыть();
Показать

Т.к. коллекция ОбъектГлавный.transaction содержит всего 1 элемент, то она читается как ОбъектXDTO, а не как СписокXDTO.
5. zaxarovsky 111 04.10.13 09:54 Сейчас в теме
А, это я просто тут в посте 1 элемент оставил для краткости. Добавлю 2 или сколько угодно, будет СписокXDTO, но это проблему не решает. Мне нужно добраться до текстовых данных... "ШОКОЛАД_Бабаевский_горький_111111111111".
Это не получается.
6. mymyka 04.10.13 10:02 Сейчас в теме
(5)имхо, второй xsd файл генерится неверно. Объявления реквизита для хранения значения элемента то там нет.
8. zaxarovsky 111 04.10.13 10:33 Сейчас в теме
(6) mymyka,
да, неверно видимо. Но даже если добавить это объявление, то при чтении
ОбъектГлавный = Фабрика.ПрочитатьXML(ОбменXML); (хоть со вторым параметром хоть без) он не читается фабрикой.
7. kasper076 109 04.10.13 10:02 Сейчас в теме
(5) zaxarovsky, да. Вижу уже, что значения не видны. Мне кажется, что дело в схеме.
9. kasper076 109 04.10.13 10:56 Сейчас в теме
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="AxaptaXMLExport">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="transaction" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Record" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Field" nillable="true" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:simpleContent msdata:ColumnName="Field_Text" msdata:Ordinal="0">
                          <xs:extension base="xs:string">
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="name" type="xs:string" />
                  <xs:attribute name="row" type="xs:string" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="version" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="version" type="xs:string" />
    </xs:complexType>
  </xs:element>
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="AxaptaXMLExport" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>
Показать


Но тут другая проблема. Не видно имен полей.
10. kasper076 109 04.10.13 12:30 Сейчас в теме
<AxaptaXMLExport xmlns:Table="urn:www.navision.com/Formats/Table" version="1.0">
    <transaction version="1.0">
        <Table:Record name="InventTableExportDC" row="1">
            <Table:Field name="ItemId">
		<Table:Field>00099B101</Table:Field>
	    </Table:Field>
            <Table:Field name="FactoryId_OK">
		<Table:Field>Остальные</Table:Field>
	    </Table:Field>
            <Table:Field name="FactoryItemId">
		<Table:Field>ББ00017-55555</Table:Field>
	    </Table:Field>
            <Table:Field name="itemName">
		<Table:Field>ШОКОЛАД_Бабаевский_горький_111111111111</Table:Field>
	    </Table:Field>
            <Table:Field name="NetWeight">
		<Table:Field>5.120</Table:Field>
	    </Table:Field>
            <Table:Field name="Quantity">
		<Table:Field>200.00</Table:Field>
	    </Table:Field>
            <Table:Field name="UnitId">
		<Table:Field>шт</Table:Field>
	    </Table:Field>
            <Table:Field name="UnitVolume"/>
            <Table:Field name="grossDepth">
		<Table:Field>387.00</Table:Field>
	    </Table:Field>
            <Table:Field name="grossHeight">
		<Table:Field>82.00</Table:Field>
	    </Table:Field>
            <Table:Field name="grossWidth">
		<Table:Field>282.00</Table:Field>
	    </Table:Field>
            <Table:Field name="standardPalletQuantity">
		<Table:Field>800.00</Table:Field>
	    </Table:Field>
            <Table:Field name="QtyPerLayer">
		<Table:Field>8.00</Table:Field>
	    </Table:Field>
            <Table:Field name="ABCRevenue"/>
            <Table:Field name="Price">
		<Table:Field>0</Table:Field>
	    </Table:Field>
            <Table:Field name="applicationtime_OK">
		<Table:Field>365</Table:Field>
	    </Table:Field>
            <Table:Field name="FactoryNE">
		<Table:Field>ББ00017B101</Table:Field>
	    </Table:Field>
            <Table:Field name="standardShowBoxQuantity">
		<Table:Field>50.00</Table:Field>
	    </Table:Field>
        </Table:Record>
    </transaction>
</AxaptaXMLExport>
Показать

Вот так нужно оформлять. Иначе не понимает.
11. zaxarovsky 111 04.10.13 13:03 Сейчас в теме
(10) kasper076,
да? у меня при чтении ФабрикаXDTO.ПрочитатьXML этого файла все-равно нету текстового значения поля.
вы как, каким способом проверяете\загружаете?
12. kasper076 109 04.10.13 13:38 Сейчас в теме
(11) zaxarovsky,
	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл("D:\Новый1.xml");      
	ОбъектГлавный = ФабрикаXDTO.ПрочитатьXML(ОбменXML);
	Для Каждого Объект1 Из ОбъектГлавный.transaction.Record.Field Цикл
		Сообщить(Объект1.name);
		Сообщить(Объект1.Field);
	КонецЦикла;
	ОбменXML.Закрыть();
Показать
13. zaxarovsky 111 04.10.13 14:24 Сейчас в теме
Ай, да! Я просто схему новую сгенерил, а файлик xml старый оставил сперва. Да, так доступно текстовое содержимое.
Однако ж, придется каждый файл обмена при загрузке сначала парсить и перезаписывать в этом формате.
Неужто не получится без этого? Это ведь стандартный формат обмена у Аксапты.
Я еще пробовал генерить xsd с помощью Altova XMLSpy. Там схема гораздо полнее формируется, что уже хорошо, но ФабрикаXDTO.ПрочитатьXML все-равно ее не хавает как надо.
14. mymyka 04.10.13 14:28 Сейчас в теме
(13)Проще читать ее через обычное ЧтениеXML, благо структура стойкая и примитивная, а все значения строковые.
15. zaxarovsky 111 04.10.13 14:38 Сейчас в теме
(14) mymyka,
Знаю, что проще, так и читаем.
Тут вопрос поставлен именно так, чтобы извернуться загрузить через XDTO, да еще и структуру исходного xml не менять. :)
16. kasper076 109 04.10.13 15:33 Сейчас в теме
(15) zaxarovsky,
	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл("D:\Новый1.xml");      
	ПостроительДОМ = Новый ПостроительDOM;
	ДокументДом = ПостроительДОМ.Прочитать(ОбменXML);
	ОбходДереваДОМ = Новый ОбходДереваDOM(ДокументДом);
	Пока ОбходДереваДОМ.СледующийУзел() <> Неопределено Цикл
		Если ОбходДереваДОМ.ТекущийУзел.ТипУзла = ТипУзлаDOM.Текст Тогда
			Продолжить;
		КонецЕсли;
		Сообщить(ОбходДереваДОМ.ТекущийУзел.ИмяЭлемента);	
		Сообщить(ОбходДереваДОМ.ТекущийУзел.ТекстовоеСодержимое);	
	КонецЦикла;	
	ОбменXML.Закрыть();
Показать

Работает с исходным файлом XML. В отладчике для ОбходДереваДОМ.ТекущийУзел можно увидеть значения атрибутов, ну и соответственно настроить их обработку.
17. mymyka 04.10.13 15:51 Сейчас в теме
(15)В выгрузке нет описания типов, все равно придется вручную присваивать. Разница лишь в том, как организовывать обход. Через ЧтениеXML.Прочитать(), dom или фабрикуxdto.
18. kasper076 109 04.10.13 16:05 Сейчас в теме
(17) mymyka, согласен. Через Фабрику вот только не выйдет без корректировки исходного файла.
19. zaxarovsky 111 04.10.13 16:26 Сейчас в теме
20. zaxarovsky 111 04.10.13 22:20 Сейчас в теме
Вот комбинация XDTO и DOM :)
	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл(ИмяФайла);      
	
	ОбъектГлавный = ФабрикаXDTO.ПрочитатьXML(ОбменXML);
	ОбменXML.Закрыть();
	
	ОбменXML.ОткрытьФайл(ИмяФайла);
	ПостроительДОМ = Новый ПостроительDOM;
	ДокументДом = ПостроительДОМ.Прочитать(ОбменXML);
	ОбменXML.Закрыть();
	
	Фильтр = Новый ФильтрУзловDOM(,,,ПараметрыОтбораУзловDOM.ОтображатьТекст);
	ОбходДереваДОМ = Новый ОбходДереваDOM(ДокументДом,, Фильтр);
	
	Для Каждого Запись Из ОбъектГлавный.transaction.Record Цикл
		Сообщить("**************Запись "+Запись.row+"****************");
		ЕстьСоответствиеАтрибуту = Истина; ИмяАтрибута = "name";
		Для Каждого Поле Из Запись.Field Цикл 
			Если ЕстьСоответствиеАтрибуту Тогда ОбходДереваДОМ.СледующийУзел(); КонецЕсли;
			
			Если ОбходДереваДОМ <> Неопределено И ОбходДереваДОМ.ТекущийУзел.РодительскийУзел.Атрибуты.ПолучитьИменованныйЭлемент(ИмяАтрибута).Значение = Поле[ИмяАтрибута] Тогда
				ТекстовоеЗначение = ОбходДереваДОМ.ТекущийУзел.ТекстовоеСодержимое; ЕстьСоответствиеАтрибуту = Истина;
			Иначе
				ТекстовоеЗначение = ""; ЕстьСоответствиеАтрибуту = Ложь;
			КонецЕсли;
			Сообщить(Поле[ИмяАтрибута]+"-----------"+ТекстовоеЗначение );  //получаем значение текстового содержимого
		КонецЦикла;
	КонецЦикла;
Показать

во вложении файлик для загрузки
Прикрепленные файлы:
InventTable.xml
21. zaxarovsky 111 05.10.13 11:43 Сейчас в теме
выводы:
1. Схема xsd не обязательна (так же как и кастомные ПакетыXDTO) при загрузке xml через ФабрикуXDTO.
2. При чтении через Фабрику не все структуры формата xml поддерживаются. Например в данном примере не читаются одновременно и атрибуты и текстовое содержимое элемента.
3. На помощь может прийти ПостроительDOM. Там структура документа загружается полностью.

Пишите, добавляйте свои пункты к выводам, если есть что сказать. В понедельник отдаю вознаграждение.
22. kasper076 109 07.10.13 08:59 Сейчас в теме
Как вариант можно еще использовать xPath и/или xsl
Вот ссылка на цикл статей

	ОбменXML = Новый ЧтениеXML;
	ОбменXML.ОткрытьФайл("D:\Новый1.xml");      
	ПостроительДОМ = Новый ПостроительDOM;
	ДокументДом = ПостроительДОМ.Прочитать(ОбменXML);
	Результат = ДокументДом.ВычислитьВыражениеXPath("/AxaptaXMLExport/transaction/Table:Record/Table:Field", ДокументДом, Новый РазыменовательПространствИменDOM(ДокументДом), ТипРезультатаDOMXPath.УпорядоченныйИтераторУзлов);
	Пока Истина Цикл
		Значение = Результат.ПолучитьСледующий();
		Если Значение = Неопределено Тогда
			Прервать;
		КонецЕсли;
		Сообщить(Значение.Атрибуты.ПолучитьИменованныйЭлемент("name").ЗначениеУзла + " = " + Значение.ТекстовоеСодержимое);
	КонецЦикла;	
Показать
23. zaxarovsky 111 07.10.13 09:38 Сейчас в теме
(22) kasper076,
О, супер! Не знал об этих возможностях, штука вообще полезная, спасибо! :)

P.S. Кстати, если кто будет использовать конструктор Новый ОбходДереваDOM с фильтром, то там параметр типа ФильтрУзловDOM надо указывать третьим по счету, а не вторым, как указано в синтаксис-помощнике (почему-то это так).
kasper076; +1 Ответить
24. zaxarovsky 111 07.10.13 16:14 Сейчас в теме
kasper076,
Спасибо за помощь! Думаю, вся полученная в ходе обсуждения информация пригодится не только мне!
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот