Как создать пустой xml файл. Преобразование в формат XML
Хотелось бы в одном месте рассказать о вполне типичной задаче при работе с XML , а именно, о создании XML на основе существующего. Данная операция будет состоять из нескольких этапов, при выполнении которых, будут решены дополнительные задачи, такие как:
- Создание XML на основе XSD , и наоборот.
- Сериализация и десериализация объектов.
- Создание класса, для будущей сериализации из XML или XSD .
XSD - это язык, для описания XML . И если вы посмотрите содержимое файла содержащего это описание, то возникнет вопрос, зачем же описывать казалось бы очевидные теги вашего XML ? Но представьте, что вы интегрируетесь с какой то внешней системой, и для обмена данных хотите использовать формат XML . Так вот, XSD позволяет описать для каждого элемента его именя, возможные атрибуты, обязательность полей или атрибутов, дать понять, что содержимое какого то тега может содержать лишь один внутренний элемент () и не более, либо узел может иметь последовательность элементов (< a> ... ). Когда внешняя система является вашей, тогда проблем может не возникнуть, но когда это сторонняя организация, тогда данное описание через XSD , будет инструментом урегулирования споров с форматом, а так же, используя утилиты, можно проверить соответствие любой XML изначальному формату.Итак, что же мы будем делать, для того, что бы научиться штамповать XML на основе вашего эталона? Опишу всё по порядку.
Имеется:
Какой то XML (xmlfile.xml)
, сохраненный в текстовом формате в файл. Ниже приведу текст:
xml
version
=
"
1.0
"
?>
<
catalog
>
<
book
id
=
"
bk101
"
>
<
author
>
Gambardella, Matthew
author
>
<
title
>
XML Developer"s Guide
title
>
<
genre
>
Computer
genre
>
<
price
>
44.95
price
>
<
publish_date
>
2000-10-01
publish_date
>
<
description
>
An in-depth look at creating applications
with XML.
description
>
book
>
<
book
id
=
"
bk102
"
>
<
author
>
Ralls, Kim
author
>
<
title
>
Midnight Rain
title
>
<
genre
>
Fantasy
genre
>
<
price
>
5.95
price
>
<
publish_date
>
2000-12-16
publish_date
>
<
description
>
A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.
description
>
book
>
catalog
>
Действия для создание нового:
- Сначала используя утилиту XSD.exe , либо воспользовавшись онлайн сервисами (искать "xml to xsd" один из них www.freeformatter.com/xsd-generator.html), мы будем создавать из имеющейся XML ее примитивное XSD описание. На выходе мы будем иметь полностью, автоматическим образом, созданный output.xsd файл, который уже подходит к использованию но может быть не полным.
- Далее, на основе output.xsd , будут созданы классы на языке C# xmlclass.cs. После чего, мы добавляем его в наш проект. Создавать класс можно используя XSD.exe, либо xsd2code утилитой, или же любым онлайн сервисом.
- Теперь мы готовы использовать классы файла xmlclass.cs . Поэтому создадим и наполним данными экземпляры xmlclass , а потом, используя процесс сериализации, будем преобразовывать объекты в XML строку, и после чего сохраним ее в новый файл. Тем самым получим XML на основе имеющегося.
Шаг 1. Создание XSD из XML.
Итак, приведу способы, которыми пользуюсь сам:- Утилита xsd.exe - создатель Microsoft .
- Утилита xsd2code.exe - стороннее приложение, которое умеет все тоже самое, что и xsd.exe , но доступно для скачивания напрямую (на данный момент стала платной с Trial периодом).
- Использование любых онлайн сервисов.
Ссылка для скачивания и установки одного из SDK
:
Windows SDK for Windows 7 and .NET Framework 4 .
Воспользуемся поиском, и найдем файл xsd.exe , после чего (что бы упростить себе работу), скопируем его в созданную в корне диска папку C:\xmltoxsd . Далее в эту же папку мы копируем наш xmlfile.xml и все готово к началу.
Отрываем "Командную строку" (Пуск -> "Выполнить" -> "cmd"), переходим в наш каталог и вызываем с параметрами по умолчанию xsd.exe
, передавая наш xmlfile.xml параметром:
И видим, что рядом появился файл xmlfile.xsd с содержимым.
Вот и все! Этих действий достаточно, для создания примитивного XSD файла, с которым можно работать. Но стоит понимать, что сам xsd.exe , как и любая другая утилита, ничего не знает про типы ваших полей (поэтому почти всегда тип полей будет string ), а так же о всех вариациях атрибутов и параметров. То есть, если у какого-то тега нет атрибута в вашей XML , тогда его и не будет в описании. Поэтому XML должен быть наиболее полным и в случае, если элемент может содержать несколько дочерних полей, лучше добавить как минимум два, что бы xsd.exe понял, что это коллекция.
Синтаксис XSD не очень сложный, поэтому, если пишется достаточно серьезное описание, возможно придется поработать и напильником.
Шаг 2. Создание Class из XSD.
Для создания класса на языке C#, нам понадобится вновь использоваться xsd.exe но уже с другим параметром /classes , передав путь к нашему xmlfile.xsd .После выполнения появится файл xmlfile.cs, содержимое которого приведено ниже в сжатом виде:
Как видите, для внутреннего элемента catalog был создан класс catalogBook , у которого поля соответствуют полям в XML , а поле Id помечено как атрибут. Xsd.exe корректно понял, что внутри catalog хранится коллекция книг, поэтому появилось свойство Items , для наполнения дочерней коллекции.
Замечание: xsd.exe не умеет добавлять комментарии к получившимся классам и полям. В описании XSD существует элемент под названием < xs:annotation > , который чаще всего содержит < xs:documentation >, внутри которого размещено описание поля. По идее, оно должно быть размещено в /// описании, но на текущий момент xsd.exe отказывается добавлять текст в описание, поэтому приходится прибегать к альтернативам, таким как xsd2code или онлайн сервисам.
Шаг 3. Сериализация объектов в XML.
Получившиеся классы у нас лежат в файле xmlfile.cs . Далее его содержимое или сам файл добавляем в проект Visual Studio , после чего можно с ним работать. Я создам демонстративный объекты книг, после чего сохраню в файл в формате XML .Private
void
Example()
{
// Создание первой книги
var
book1 = new
catalogBook
()
{
author = "King"
,
description = "Very interesting book"
,
genre = "Fantasy"
,
price = 22.ToString(),
id = "42011"
,
title = "It"
};
// Создание второй книги
var
book2 = new
catalogBook
()
{
author = "O"Brien, Tim"
,
description = "Microsoft"s .NET initiative is explored in detail in this deep programmer"s reference."
,
genre = "Computer"
,
price = 36.ToString(),
id = "30012"
,
title = "Microsoft .NET: The Programming Bible"
};
// Создание корневого элемента каталога, содержащего две книги выше
var
catalog = new
catalog
()
{
Items = new
{ book1, book2 }
};
// Содержит XML объекта catalog
var
xmlCatalog = Serialize(catalog);
// Записываем строку в файл
//
TODO Сделано для демонстрации. Желательно вызывая метод Serialize передавать Stream к файлу
File
.WriteAllText("Output.xml"
, xmlCatalog);
}
private
string
Serialize
Появилась задача создания XML файла на основе XSD схемы. Поиски по форумам приводили к большому количеству обсуждений, связанных с непониманием процесса, и всего к паре статей объясняющих суть. Люди задавали вопросы, бились над решением, но после того как задача поддавалась им, просто исчезали, не описав механизм. Это подтолкнуло на создание простого описания процесса.
P.S. Не ругайтесь сильно, моей целью не было создание некой наукообразной статьи, строго использующей правильную терминологию, а желание просто помочь сделать первый шаг к пониманию очень мощного механизма обмена через XML.
P.P.S. Сразу должен оговориться, что прилагаемый к статье файл выгрузки является только заготовкой, создающей только часть требуемой структуры XML файла, т.к. моя работа с этой выгрузкой имела скорее познавательный характер (копировать предыдущий документ по экспорту на сайте ФТС и загружать из Excel"овского файла только табличную часть Товары представилось более эффективным решением), а недостаток времени не позволял дописать создание всей структуры, исходя только из соображений перфекционизма.
Итак, зарегистрировавшись на сайте ФТС, стало понятно, что для создания документов Статистической отчетности по экспорту требуется выгрузка данных из документов Реализация товаров и услуг Управления торговлей и создания файла для загрузки.
Там возможно два варианта загрузки.
Первый: загрузка табличной части с Товарами из файла Excel (этот вариант и был выбран как рабочий, т.к. имел те плюсы, что не надо было возиться с обработкой "Шапки" документа, а можно было просто копировать предыдущий, изменив в "Шапке" то, что требовалось).
Второй: создание XML файла по схеме скачаной с сайта ФТС в виде "Альбома форматов электронных форм документов". Альбом представляет из себя достаточно большое количество XSD схем. В них была найдена схема "Статистической формы учета перемещения товара" и дополнительные файлы с описаниями типов для нее. Схемы прилагаются к статье в архиве с обработкой.
Для просмотра XSD схем использовался бесплатный Майкрософтовский XML Notepad 2007.
На изображении показан основной файл со схемой XSD "Статистическая форма учета перемещения товара". На изображении выделены основные блоки XSD схемы, требуемые нам для ее понимания.
Из схемы видно, что нам надо получить XML файл, заполненый структурой, указанной в ветке "xs:element" типа StaticFormType.
Структура может быть достаточно сложной (как и в нашем случае). С описаниями типов, присутствующими непосредственно в ветке, вынесенными в отдельную ветку или даже находящимися в другом файле.
Данная структура имеет тип StaticFormType, который в свою очередь, состоит из базового типа BaseDocType, набора объектов разных типов и текстовых аттрибутов.
Базовый тип BaseDocStyle описывается в другом файле (и пространстве имен)
.
Этот файл содержит в себе еще массу типов, которые не используются в нашем случае.
Теперь перейдем к работе в 1С. В двух словах, то что нам надо сделать сводится к следующему:
1. Создается ФабрикаXDTO
НашаФабрикаXDTO = СоздатьФабрикуXDTO(МассивПолныхИменФайловСоСхемамиXSD);
2. В фабрикеXDTO создаются все сложные типы данных, которые далее мы будем заполнять в создаваемом файле XML:
StaticFormType = МояФабрикаXDTO.Тип("urn:customs.ru:Information:CustomsDocuments:StaticForm:5.4.0", "StaticFormType");
Типы данных, входящих в некий тип, можно получить из коллекции его свойств:
CUOrganizationType = StaticFormType.Свойства.Получить("Consignee").Тип; NameType = CUOrganizationType.Свойства.Получить("OrganizationName").Тип; ShortNameType = CUOrganizationType.Свойства.Получить("ShortName").Тип; LanguageCodeType = CUOrganizationType.Свойства.Получить("OrganizationLanguage").Тип;
3. Когда все сложные типа данных созданы, создаем на их основе структуру XML файла, состоящую из объектов ФабрикиXDTO:
StaticFormType_ОбъектXDTO = МояФабрикаXDTO.Создать(StaticFormType); // коллекция с документами NewDocuments = МояФабрикаXDTO.Создать(DocumentsType); NewDocuments.PrDocumentName = МояФабрикаXDTO.Создать(PrDocumentNameType, "Товарная накладная"); NewDocuments.PrDocumentNumber = МояФабрикаXDTO.Создать(PrDocumentNumberType, "123-номер"); NewDocuments.PrDocumentDate = МояФабрикаXDTO.Создать(PrDocumentDateType, "2014-10-05"); StaticFormType_ОбъектXDTO.Documents.Добавить(NewDocuments);
Одновременно заполняем элементарные (простых типов) реквизиты.
4. Ну и наконец выгружаем все из ФабрикиXDTO в файл:
ФайлXML = Новый ЗаписьXML(); ФайлXML.ОткрытьФайл(ИмяФайла); ФайлXML.ЗаписатьОбъявлениеXML(); МояФабрикаXDTO.ЗаписатьXML(ФайлXML, StaticFormType_ОбъектXDTO); ФайлXML.Закрыть();
P.S. В архиве содержится файл заготовки выгрузки в XML (создаются только некоторые реквизиты, отражающие все случае заполнения файла) и схемы XSD.
Разархивировать все файлы в некоторую директорию.
XML будет создаваться в ней же.
1. ВведениеЕсли кто-либо из вас когда-нибудь пытался изучить XML своими силами, Вы возможно встречались со многими сбивающими
с толку понятиями, обрушившимися и на меня в свое время. DTD, XML Schema, пространства имен (namespaces), XPath,
XPointers, XSL, XSLT, DOM, SAX, SOAP, Все, я сдаюсь. Добавлю лишь, что большинство из этих материалов основано
на реализациях, код которых может содержать ошибки. Наверняка существуют миллионы способов реализации и
использования XML, но они все могут быть достаточно сложны. А знаете, XML может быть и очень простым. Если мы
забудем про DTD, XML Schemas, пространства имен (namespaces), и т.п.
Стараясь быстрее обучить вас работе с XML, я буду по возможности игнорировать приличную долю информации, которую
вы и так сможете прочитать в соответствующей литературе. И первое что я собираюсь проигнорировать, это пространства
имен (namespaces) и схемы (schemas). Вам это может показаться странным, так как большинство книг начинаются именно
с объяснения этих понятий, но постарайтесь думать об XML как о средстве решить конкретную задачу, как, например,
о молотке. Для того чтобы пользоваться молотком, разве обязательно знать, как построить дом? Что если все что
мне нужно, это просто вбить гвоздь чтобы повесить на него картину? То же самое и с XML, он может быть и очень
сложным, достаточно универсальным для использования в сотнях, если не в тысячах приложений, и очень простым, если
не обращать внимания на некоторые вещи. В этой статье, я буду концентрироваться на решении конкретных проблем с
помощью XML.
Так в чем же собственно проблема? Давайте предположим, что я хочу описать простой объект, например стакан,
используя XML. Зачем я собираюсь использовать XML для этого? Ну, во-первых, это как раз то, для чего и предназначен
XML. XML описывает данные. В моем примере, стакан, это и есть данные. В жизни, данными могут быть документы Word,
листы электронных таблиц, изображения, книга, запись базы данных, или даже классы C++ или Visual Basic. Во вторых,
XML расширяем. XML позволяет мне создавать столько признаков, сколько необходимо для описания данных и эти признаки
будут такими, какими я захочу. И, наконец, потому что XML быстро становится стандартом. Если на Марсе есть жизнь,
то можете не сомневаться, что они там смогут понять мой XML файл.
Какие основные свойства позволяют описать стакан?
Как бы то же самое выглядело в формате XML?
|
Заметьте, что первая строка файла () имеет специальный вид, пока, просто запомните, что она
должна быть тут. Прелесть формата XML в том, что любой может понять, о чем в нем говориться, просто внимательней
взглянув на него. Понятно также, что это не единственное из возможных XML описаний стакана. Если я попрошу 10
человек разработать XML описание стакана с одинаковыми свойствами, возможно, все они создадут разные, но верные
описания. Вот тут как раз и кроется проблема. Возможно не для нас, людей, но когда компьютер читает XML файл,
то было бы отличной идеей, дать ему знать, о чем этот файл. Вот тут и всплывает пространство имен (namespaces)
и схемы (schemes). Проще говоря, схемы используются для определения адекватной структуры для XML файла.
Теперь настало время поговорить о нескольких простых правилах XML, которым необходимо придерживаться:
Правило XML #1 : Адекватный XML файл должен в точности соответствовать своей схеме. Но для простоты понимания материала, ни один из моих примеров не будет использовать схемы. Таким образом, строго говоря, ни один из моих примеров не "адекватный". Но, честно говоря, мне все равно. Я не собираюсь строить дом, мне нужно всего лишь повесить картину. Я подробней расскажу об этом позже, когда будем обсуждать объектную модель документов XML.
Правило XML #2 : Если вы программируете на VB, запомните: XML чувствителен к регистру. XML чувствителен к регистру. XML чувствителен к регистру. XML чувствителен к регистру. Напишите это предложение 1000 раз и никогда не забудете.
Правило XML #3
: Тэги принято называть элементами и каждый открывающийся тэг, должен иметь соответствующий ему
закрывающийся тэг. Следуя этому правилу, у вас получится правильный XML файл. Это очень важно, потому что до тех
пор, пока XML файл не будет правильно оформлен, он не будет проанализирован и не загрузится в объектную модель
документов. Заметьте, если элемент не содержит значений и не содержит других (вложенных) элементов, закрывающий
тэг может иметь вид
Правило XML #4 : Элементы могут содержать атрибуты, а значения атрибутов должны быть заключены в кавычки (одинарные или двойные).
Правило XML #5
: Можно несколько раз использовать имена атрибутов, но имена элементов должны быть уникальны для
всего файла. В предыдущем примере, атрибут qty имел различное значение в зависимости от того, в каком элементе
он используется
Правило XML #6 : В XML есть несколько специальных символов, которые не могут быть использованы напрямую, потому что являются зарезервированными в синтаксисе XML. Поэтому, для использования таких символов, придется использовать зарезервированную конструкцию, начинающуюся с символа & и специального кода, (символ & должен писаться как &) (символ " должен писаться как ") (символ < должен писаться как <) (символ > должен писаться как >) и (символ " должен писаться как "). Вместо этого, также можно использовать инструкцию , где на месте "...." может быть любая последовательность символов, кроме "]]>". Такая конструкция может встречаться в любом месте, но она не может быть вложенной.
2. Объектная модель документов XML
Объектная модель документов XML позволяет программистам загружать содержимое XML файла в память. Как только XML файл загружен таким образом, с ним можно работать, используя свойства, методы и события объектной модели документов. Вот где как раз и проявляется польза XML. Объектная модель документов значительно облегчает выборку и обработку информации XML файла. Я не буду тут рассказывать обо всех возможностях объектной модели документов, расскажу лишь о некоторых основных возможностях, которые помогут в достижении цели этой статьи. Я возьму только что созданный XML файл с описанием стакана, загружу его в объектную модель документов и проделаю несколько действий с ним. Остальные особенности и возможности объектной модели документов я приберегу для следующей статьи, рассказывающей о клиентском XML. Заметьте, не смотря на то, что объектная модель документов очень хороша и удобна для разработчиков, она требует довольно значительного объема системных ресурсов. Поэтому существует еще один метод анализа XML файлов, известный как SAX. Моя статья не претендует на исчерпывающий источник информации по этому вопросу, поэтому было бы полезно также воспользоваться XML SDK.
Давайте посмотрим на пример, используя анализатор Microsoft"s XML версии 3.0 (Microsoft"s XML parser version 3.0
(msxml3.dll)) чтобы разобраться, как же это все работает. Если у вас нет анализатора, то последнюю версию можно
скачать с сайта Microsoft.
Предположим, я сохранил пример описания стакана в формате XML в файл "http://web_server/xml/cup.xml" (локальный
путь C:\inetpub\wwwroot\xml\cup.xml) и теперь хочу загрузить его в объектную модель документов. Следующий код
предполагает, что анализатор уже загружен и работает.
Код на Visual Basic 6.0: (устанавливаем связь с Microsoft XML, v3.0) Dim xmlDoc as MSXML2.DOMDocument30 Set xmlDoc = New DOMDocument30 xmlDoc.async = False xmlDoc.validateOnParse = False xmlDoc.load ("c:\inetpub\wwwroot\xml\cup.xml") msgBox xmlDoc.xml ASP Server-Side код на Visual Basic: Dim xmlDoc Set xmlDoc = Server.CreateObject("Msxml2.DOMDocument.3.0") xmlDoc.async = False xmlDoc.validateOnParse = False xmlDoc.load "/xml/cup.xml" ASP Server-Side код на Java Script: var xmlDoc = Server.CreateObject("Msxml2.DOMDocument.3.0"); xmlDoc.async = false; xmlDoc.validateOnParse = false; xmlDoc.load ("/xml/cup.xml"); |
Пояснение приведённого кода - пройдемся по коду на VB6
Строка 1: Dim xmlDoc as MSXML2.DOMDocument30
В этой первой строке определяем ссылку на "Microsoft XML, v3.0". В этой строке я определил переменную xmlDoc как ссылку на XML документ. MSXML2 это библиотека (используйте это название, не пытайтесь написать MSXML3, это не будет работать). DOMDocument30 определяет объект XML документа соответствующий версии 3.0. Вы также можете встретить такой код: dim xmlDoc as MSXML2.DOMDocument. Такой конструкцией обычно пользуются, когда не хотят указывать конкретную версию XML документа. В этом случае будет использоваться зарегистрированный по умолчанию в системе анализатор. Проблема может быть только в том, что версия анализатора, зарегистрированная по умолчанию, может отличаться на разных компьютерах. Если вы хотите быть уверенными в том, что написанный вами код будет работать с любой версией анализатора, то не используйте в нем специфических для конкретных версий анализатора конструкций. Потому, что нет никакой гарантии, что у пользователя, который будет пользоваться вашим кодом, установлена имена та версия анализатора, под которую вы писали свой код. Еще одно преимущество разработки кода, независимого от версии анализатора в том, что когда выходит более новая версия анализатора, у нее обязательно будет обратная совместимость с предыдущими версиями, и вам не придется перекомпилировать ваш код.
Строка 2: Set xmlDoc = new DOMDocument30
В этой строке происходит инициализация переменной xmlDoc как нового экземпляра объекта XML документа версии 3.0.
Строка 3: xmlDoc.async = False
Файлы XML могут быть загружены либо в синхронном, либо в асинхронном режиме. Если xmlDoc.async = False, то значит, что содержимое XML фала будет загружено, и только после этого управление будет передано вызывающему процессу. Если xmlDoc.async = True, то значит, что управление будет передано вызывающему процессу сразу, не дожидаясь, пока содержимое XML файла будет полностью загружено.
Строка 4: xmlDoc.validateOnParse = False
Этот код сообщает о том, что анализатор не должен проверять загружаемый XML файл на соответствие своей схеме (validateOnParse = False). Для того, чтобы включить проверку на соответствие схемы, нужно написать validateOnParse = True.
Строка 5: xmlDoc.load ("C:\inetpub\wwwroot\xml\cup.xml")
В этой строке вызывается метод загрузки указанного XML файла. Существует два вида метода загрузки. Первый, который написан в строке 5, загружает файл в объектную модель документов, и при этом нужно обязательно передавать полный путь до XML файла. Второй вариант загрузки предусматривает передачу в качестве параметра xml строку. Такой вид загрузки мог бы быть вызван, например, так: xmlDoc.loadXML("корректная xml строка"). Я покажу, как пользоваться этим способом позже.
Строка 6: MsgBox xmlDoc.xml
Эта строка отображает содержимое загруженного XML файла. В результате мы должны получить тот исходный XML файл, который создали ранее.
2.2. Исследование объектной модели документов XML
Создайте в Visual Basic новый проект и назовите его standard.exe. Вставьте приведенный выше код в метод загрузки главного окна вашего проекта. Убедитесь, что вы объявили ссылку именно на "Microsoft XML v3.0". Для того, чтобы это сделать, нажмите Project-->References, затем пролистайте появившийся список вниз и найдите в нем нужную ссылку. Заметьте, анализатор версии 3.0 должен быть установлен на вашем компьютере, иначе в списке его не будет. Установите точки остановки на последней строке кода (msgbox xmlDoc.xml). Запустите приложение в режиме отладки. Когда процесс выполнения дойдет до точки остановки, вызовите окно "Locals" и посмотрите объектную модель документов. Можно многое узнать, просматривая то, что отображено в этом окне. Окно "Locals" должно быть похоже на то, что изображено на рисунке ниже. Вот некоторые интересные свойства объектной модели документов.
Объектная модель документов XML всегда содержит два узла верхнего уровня:
- Item1 это корень ветви элементов документа (не обращайте на нее внимания)
- Item2 на самом деле первый элемент документа (запомните это)
nodeName или baseName - могут быть использованы при поиске имени элемента или атрибута.
nodeType - используйте для того, чтобы получить тип текущего узла.
nodeValue - используете для того, чтобы узнать значение данных узла.
childNodes - это коллекция узлов-потомков. Они могут быть узлами элементов, текстовыми узлами и узлами CDATA.
Могут быть и другие типы узлов, про которые я сейчас рассказывать не стану, но вы сможете узнать все про них в
XML SDK.
attributes - это коллекция узлов атрибутов текущего элемента.
length - используется для определения количества узлов в дереве непосредственно принадлежащих текущему.
xml - это свойство присутствует во всех узлах и может быть использовано для представления текущей позиции в
документе. XML строка начинается с текущего узла и проходит вниз до конца дерева. Это очень полезное свойство.
Поэкспериментируете с ним и увидите, что получится.
2.2.2. Узлы элементов
Узел элементов может содержать узлы потомки элементов, атрибутов, текста или CDATA. Из рисунка ниже видна следующая информация об узле "SOLID":
nodeType - Тип текущего узла = NODE_ELEMENT - т.е. текущий узел является элементом.
nodeName или baseName или tagName - Название текущего узла (элемента) = SOLID.
Его родительский элемент CONTENTS имеет 4 потомков.
Это можно увидеть на следующем рисунке, но SOLID имеет одного потомка, который имеет текстовый тип данных.
text - "ice cube" это сокращенный метод, позволяющий получить значение текущего узла без перемещения к текстовому
узлу потомка.
2.2.3. Узлы атрибутов
Узлы атрибутов могут состоять только из текстовых или CDATA узлов-потомков. На следующем рисунке показано, какая информация может быть получена об узле "qty":
nodeType - Тип текущего узла = NODE_ATTRIBUTE - текущий узел является атрибутом.
nodeName или baseName - Имя текущего узла (Атрибутов) = qty
Из следующего рисунка также понятно, что qty имеет одного потомка, который имеет текстовый тип данных.
text или value - "2" это сокращенный метод, позволяющий получить значение текущего узла без перемещения к
текстовому узлу потомка.
2.2.4. Текстовые узлы и узлы CDATA
Текстовые или CDATA узлы не содержат потомков. Текстовые узлы содержат обработанные текстовые данные своего родительского узла. CDATA содержат необработанные текстовые данные своего родительского узла. CDATA узлы создаются, когда данные в XML файле специальным образом обрамлены. Метка CDATA говорит анализатору не разбирать данные и принимать символы внутри этой метки как данные. Секция CDATA особенно полезна, когда нужно вставить код внутрь XML файла. На следующем рисунке показано, какая информация может быть получена из текущего текстового узла:
nodeType - Тип текущего узла = NODE_TEXT - текущий узел содержит текстовые данные.
nodeName - Имя текущего узла (текстового) = #text - все текстовые узлы называются #text
data или text или value - "2" - это текущие данные узла.
2.2.5. Ошибки при загрузке документа
Секция parseError объектной модели документов может оказаться полезно при выявлении проблем, возникающих при загрузке XML документа. Если я удалю закрывающий тег от OTHER в файле нашего примера и попытаюсь запустить программу еще раз, то получу следующий результат. Первая часть полезной информации, это то, что наш nextSibling теперь содержит значение Nothing. Теперь, если вы посмотрите на childNodes, вы можете увидеть, что поле length теперь равно 0. Оба этих признака говорят о том, что наш XML документ не был загружен. Чтобы разобраться почему, я открываю узел parseError и получаю всю информацию об ошибках.
Итак, я показал вам, как загрузить XML файл в объектную модель документов, но что с ним там делать? Одна из основных возможностей, которой вы сможете пользоваться это выполнять различные запросы к XML документу. Для этого вы конечно можете просматривать весь документ до тех пор, пока не найдете информацию которую ищите. Но наиболее предпочтительный способ, это использование одного из двух методов класса DOMDocument. Два метода используемые для поиска узлов в нашем предыдущем примере могли бы выглядеть как xmlDoc.SelectSingleNode(patternString) - для получения искомого узла, или xmlDoc.SelectNodes(patternString) - для получения списка искомых узлов. Параметр patternString как раз и является запросом. Он может быть сформирован одним из двух способов. Либо как XSL запрос, либо как XPath запрос. Более новый и предпочтительный способ создавать запросы к XML документу, это XPath. Формат patternString должен быть установлен заранее, перед первым вызовом любого из двух методов запроса данных, иначе по умолчанию будет использоваться XSL способ формирования запросов. Для установки типа формирования patternString используйте setProperty("SelectionLanguage", "format"). Для того, чтобы изменить запросы в нашем примере таким образом, чтобы использовался способ XPath, я добавлю следующую команду: setProperty("SelectionLanguage","XPath"). По-моему, XPath это самая важная технология в XML которую следует изучить. Я приведу несколько простых XPath запросов. Хорошим началом для изучения этой технологии может служить Microsoft XML SDK. Еще одним способом для объяснения этого, могло бы быть написание простого приложения на Visual Basic, которое позволяет вводить запросы и выводить результат. Вы, возможно, найдете какие-нибудь бесплатные приложения, которые делают то же самое, но XPath довольно новый и может не вполне поддерживаться этими приложениями.
2.3.1. Использование XPATH для выполнения запросов к объектной модели документов
Давайте добавим некоторый код в конец нашего предыдущего примера для того, чтобы возвратить содержимое нашего стакана:
ОТЛИЧНО! Давайте теперь добавим еще один запрос, который позволит нам определить, есть ли у стакана крышка или нет. Добавьте следующий код в конец предыдущего:
Set objNode = xmlDoc.selectSingleNode("/CUP/LID") if objNode.text="yes" then MsgBox "We have a lid" else MsgBox "No lid on this cup" end if |
Пройдемся по коду строка за строкой:
Строка 1 : Dim objNode As IXMLDOMNode
В этой строке определяется переменная objNode типа узел XML документа. Важно понимать, что узел XML документа это тоже объект. Это не значение. Он состоит сам из себя, также как и его атрибуты и потомку (childNodes). Этим способом вы можете отсекать ненужные ветви дерева, выбирая только нужные.
Строка 2 : Dim objListOfNodes As IXMLDOMNodeList
В этой строке определяется переменная objListOfNodes имеющая тип списка узлов XML документа (группы узлов).
Строка 3 : xmlDoc.setProperty "SelectionLanguage", "XPath"
Эта строка устанавливает способ формирования patternString как XPath.
Строка 4 : MsgBox "Your cup contains the following items:"
Строка 5 : Set objListOfNodes = xmlDoc.selectNodes("//CONTENTS/*[@qty>0]")
Эта строка выполняет XPath запрос, который вернет группу узлов и сохранит их в переменной objListOfNodes. Запрос разбит на следующие части:
- //CONTENTS - взять все элементы CONTENTS в XML документе. Заметьте: // - это краткое обозначение для всего содержимого XML документа.
- /* - из списка элементов CONTENTS взять все (* - используется для указания всех) элементы-потомки. Это сокращает
полученный результат до четырех узлов элементов (
). Эти четыре узла попадают напрямую под узел CONTENTS. - [@qty>0] - проверить каждый элемент-потомок на то, чтобы его атрибут qty (@ - означает атрибут) был больше 0.
Если это условие не выполняется, узел отбрасывается. Все, что внутри в XPath запросе может принимать значения
True или False. Если результат True, то узел сохраняется. Если результат False, то узел отбрасывается. После
этого наш результат сокращается до трех узлов (
Строка 6-8 : For Each objNode In objListOfNodes / MsgBox objNode.Text / Next
Эти строки отображают значения каждого узла элемента, которые соответствуют запросу. ("ice cube" , "straw" , "water").
Строка 9 : Set objNode = xmlDoc.selectSingleNode("/CUP/LID")
Эта строка возвращает все элементы LID, которые принадлежат элементу CUP, который, в свою очередь, порожден от корня дерева (когда запрос начинается с /, то это означает что начинать нужно с корня). Это очень похоже на путь к файлу или папке. В нашем примере, этот запрос вернет элемент LID, который содержит значение "yes". Важно тут то, что я указал запросу начинать с корневого элемента XML документа. Запросы не всегда начинают выполняться с корневых элементов, обычно они начинаются с текущего узла. В нашем примере это не имеет значения, поскольку текущим узлом (xmlDoc) и является корневой элемент XML документа (но не во всех случаях это так).
Строка 10-15
: if objNode.text="yes" then / MsgBox "We have a lid" /
else / MsgBox "No lid on this cup" /end if
Эта строка отображает сообщение "We have a lid" потому, что текстовое свойство элемента LID "yes".
3. Преобразование ADO в XML
Теперь, когда вы поняли основы XML, давайте создадим элемент управления ActiveX, который будет конвертировать набор данных ADO в XML формат. Цель в том, чтобы получить наименования книг из таблицы Titles базы данных Pubs и вернуть их в формате XML. Результат, который получится я буду использовать в своей следующей статье. Вы можете сказать, ADO имеет свои собственные методы для сохранения результата в формате XML, правильно? Да, но если доверить это ADO, то в итоге я получу XML файл в таком ужасном формате, что с ним невозможно будет работать. ADO создаст XML файл с использованием пространства имен, а мне сейчас это совсем не нужно. Во-вторых, ADO создаст XML файл, который будет представлен в форме атрибутов. Иными словами, каждая запись станет элементом и каждое поле - атрибутом:
|
А мне бы хотелось получить XML файл в форме элементов, где каждая запись, содержалась бы в теге
|
Кстати, то, что я только что сделал, это создал схему для моей XML строки. Теперь, если мне нужно сверить структуру
XML документа со схемой, все что мне останется сделать, это преобразовать схему в правильный формат. То есть в
синтаксис DTD или XDR. Заметьте, что я добавил некоторые атрибуты к каждому элементу
|
Теперь я получил что-то, с чем можно работать!
Листинг 1 - CUP.XML
|
Dim xmlDoc As MSXML2.DOMDocument30 Set xmlDoc = New DOMDocument30 xmlDoc.async = False xmlDoc.validateOnParse = False xmlDoc.Load ("c:\inetpub\wwwroot\xml\cup.xml") MsgBox xmlDoc.xml Dim objNode As IXMLDOMNode Dim objListOfNodes As IXMLDOMNodeList xmlDoc.setProperty "SelectionLanguage", "XPath" MsgBox "Your cup contains the following items" Set objListOfNodes = xmlDoc.selectNodes("//CONTENTS/*[@qty>0]") For Each objNode In objListOfNodes MsgBox objNode.Text Next Set objNode = xmlDoc.selectSingleNode("/CUP/LID") If objNode.Text = "yes" Then MsgBox "We have a lid" Else MsgBox "No lid on this cup" End If |
Листинг 3 - Элемент управления ActiveX: ADO в XML (WebClass.dll)(xmlControl.cls)
Option Explicit
"Declare Database variables
Private m_dbConnection As New ADODB.Connection
Private m_dbCommand As ADODB.Command
Private m_adoRs As ADODB.Recordset
Private m_adoErrors As ADODB.Errors
Private m_adoErr As Error
Public nCommandTimeOut As Variant
Public nConnectionTimeOut As Variant
Public strConnect As Variant
Public strAppName As String
Public strLogPath As String
Public strDatabase As String
Public strUser As String
Public strPassword As String
Public strServer As String
Public strVersion As String
Public lMSADO As Boolean
"Private Global Variables
Private gnErrNum As Variant
Private gstrErrDesc As Variant
Private gstrErrSrc As Variant
Private gstrDB As String
Private gstrADOError As String
Private Const adLeonNoRecordset As Integer = 129
Private gtableName(6) As String
Private gcolumnName(6) As String
Private gprettyName(6) As String
Private gdatatype(6) As String
Private gfilter(6) As String
Private Function OpenDatabase()
If Len(strConnect) = 0 Then "устанавливаем значения по умолчанию
If Len(strDatabase) = 0 Then
strDatabase = "pubs"
End If
If nConnectionTimeOut = 0 Then
nConnectionTimeOut = 600
End If
If nCommandTimeOut = 0 Then
nCommandTimeOut = 600
End If
If Len(strAppName) = 0 Then
strAppName = "xmlControl"
End If
If Len(strUser) = 0 Then
strUser = "sa"
End If
If Len(strPassword) = 0 Then
strPassword = ""
End If
strConnect = "Provider=SQLOLEDB.1; " & _
"Application Name=" & strAppName & _
"; Data Source=" & strServer & "; Initial Catalog=" & strDatabase & "; " & _
" User ID=" & strUser & "; Password=" & strPassword & ";"
End If
"подключаемся к SQL Server и открываем базу данных
On Error GoTo SQLErr "Включаем обработчик ошибок
With m_dbConnection
.ConnectionTimeout = nConnectionTimeOut
.CommandTimeout = nCommandTimeOut
.Open strConnect "открываем базу данных, используя строку подключения
End With
On Error GoTo 0 "выключаем обработчик ошибок
OpenDatabase = True "база данных открыта успешно
Exit Function
SQLErr:
Call logerror("OPEN")
OpenDatabase = False
End Function
Private Function BuildSQLwhere(tmpWhere) As String
"Это на будущее
End Function
Public Function GetTitlesXML(Optional xmlWhere As Variant) As String
Dim whereClause As String
Dim strSQL As String
Call OpenDatabase "открываем базу данных pubs
If IsMissing(xmlWhere) Then "когда запрос не прошел
whereClause = ""
Else
whereClause = BuildSQLwhere(xmlWhere)"конвертируем запрос в правильный sql
End If
"инициализируем sql выражение которое будет запрашивать заголовки книг
strSQL = "select title_id,title,type,price,ytd_sales,notes,pubdate from titles " & whereClause
Call NewRecordSet "создаем набор данных
"устанавливаем cursorlocation
m_adoRs.CursorLocation = adUseClient
"открываем набор записей
m_adoRs.Open strSQL, m_dbConnection, adOpenForwardOnly, adLockReadOnly, adCmdText
"отключаемся от набора данных
Set m_adoRs.ActiveConnection = Nothing
On Error GoTo 0 "выключаем обработчик ошибок
"закрываем базу данных и освобождаем подключение
Call CloseDatabase
If m_adoRs.EOF Then
GetTitlesXML = "" "запрос не вернул ни одного значения
Else
If lMSADO Then
GetTitlesXML = msado(m_adoRs) "конвертируем набор данных в Microsoftado-->xml
Else
GetTitlesXML = ADOtoXML(m_adoRs, True) "convert the ado recordset to custom xml
End If
End If
"закрываем набор данных
Call CloseRecordset
Exit Function
SQLErr:
Call logerror(strSQL)
End Function
Private Function ADOtoXML(tmprs As ADODB.Recordset, tmpMP As Boolean) As String
Dim adoFields As ADODB.Fields "объявляем коллекцию для хранения полей
Dim adoField As ADODB.Field "используется для получения каждого поля из коллекции
Dim xmlDoc As msxml2.DOMDocument30
Dim tmpLine As String "хранит xml представление каждой книги
Dim tmpXML As String "служит для конкатенации xml строк
Dim i As Integer
If tmprs.EOF Then "запрос не вернул ни одну запись
ADOtoXML = ""
Exit Function
Else
Set adoFields = tmprs.Fields "создаем коллекцию полей
End If
tmpXML = " |
Листинг 4 - Тестовое приложение на VB для проверки WebClass
Private Sub Command1_Click() Dim objWC As xmlControl Dim xml As String Set objWC = New xmlControl objWC.strDatabase = "pubs" objWC.strServer = "ltweb" objWC.strUser = "sa" objWC.strPassword = "" objWC.lMSADO = Option2.Value objWC.strAppName = "Article1" Text1.Text = objWC.getTitlesXML End Sub |
Листинг 5 - ASP для тестирования WebClass
Если необходимо создать файл XML-данных и файл схемы XML из диапазона ячеек на листе, можно использовать версию 1.1 надстройки "Средства XML для Excel 2003" для расширения существующих возможностей XML в Microsoft Excel 2007 и более поздних версиях.
Примечание: Эта надстройка была разработана для Excel 2003. Документация и пользовательский интерфейс ссылаются на списки, которые в версиях приложения позднее Excel 2003 называются таблицами Excel.
Дополнительные сведения о работе с этой надстройкой см. в статье Использование надстройки "Средства XML" версии 1.1 для Excel 2003 .
Этап 2. Преобразование диапазона ячеек в таблицу XML
Нажмите кнопку ОК .
В выделенную строку в модуле кода VBA удалите из строки «50». Другими словами, изменение:
XMLDoc как msxml 2 . DOMDocument50
Кому:
XMLDocкак MSXML2 описывается. DOMDocumentНажмите клавишу F5 для поиска следующей строки, содержащей текст "XMLDoc As msxml2.DOMDocument50", нажмите кнопку ОК и измените строку, как в предыдущем пункте.
Нажмите F5 еще раз, чтобы найти и изменить другие экземпляры строки.
Если после нажатия клавиши F5 сообщения об ошибке VBA больше не отображается, закройте редактор Visual Basic, чтобы вернуться в книгу. Диапазон ячеек будет преобразован в XML-таблицу.
Примечание: Чтобы отобразить все карты XML в книге, на вкладке Разработчик в группе XML нажмите кнопку Источник для отображения области задач «Источник XML». В нижней части области задач «Источник XML» нажмите кнопку Карты XML .
Если вкладка Разработчик не видна, выполните три первых действия, указанных в следующем разделе, чтобы добавить ее на ленту Excel.
Введите данные, для которых необходимо создать файл XML-данных и файл схемы XML. Данные должны быть представлены в табличном формате в виде столбцов и строк (так называемые обычные данные).
На вкладке Надстройки в группе Команды меню щелкните стрелку возле надписи Средства , а затем нажмите кнопку Преобразовать диапазон в список XML .
Введите диапазон ячеек с данными, которые необходимо преобразовать, как абсолютную ссылку в текстовом поле.
В поле Первая строка содержит имена столбцов выберите Нет , если первая строка содержит данные, или Да , если первая строка содержит заголовки столбцов, и нажмите кнопку ОК .
Excel автоматически создаст схему XML, выполнит привязку ячеек к схеме и создаст таблицу XML.
Важно: Если откроется редактор Visual Basic и отобразится сообщение об ошибке Visual Basic for Applications (VBA), выполните следующие действия.
Действие 3. Экспорт XML-таблицы в файл XML-данных (XML)
Примечание: При создании карт XML и экспорте данных в Excel в XML-файлы существует ограничение на количество строк, которые можно экспортировать. При экспорте в XML-файл из Excel можно сохранить до 65 536 строк. Если файл содержит более 65 536 строк, Excel сможет экспортировать только первые строки (число строк mod 65 537). Например, если лист содержит 70 000 строк, Excel экспортирует 4464 строки (70 000 mod 65 537). Мы рекомендуем последовать одному из следующих советов: 1) используйте формат XLSX; 2) сохраните файл в формате "Таблица XML 2003 (*.xml)" (при этом будут потеряны сопоставления); 3) удалите все строки после 65 536 и затем снова выполните экспорт (при этом сопоставления сохранятся, но будут потеряны строки в конце файла).
XML – это универсальный формат работы с данными. Его поддерживает множество программ, в том числе из сферы СУБД. Поэтому конвертация информации в XML важна именно с точки зрения взаимодействия и обмена данными между различными приложениями. Excel как раз входит в число программ, которые работают с таблицами, и даже может выполнять манипуляции с базами данных. Разберемся, как конвертировать файлы Эксель в XML.
Конвертация данных в формат XML не такой уж простой процесс, так как в его ходе должна быть создана специальная схема (schema.xml). Впрочем, для преобразования информации в простейший файл данного формата достаточно иметь под рукой обычные инструменты сохранения в Excel, а вот для создания хорошо структурированного элемента придется основательно повозиться с составлением схемы и её подключением к документу.
Способ 1: простое сохранение
В Excel можно сохранить данные в формате XML, просто воспользовавшись меню «Сохранить как…» . Правда, нет гарантии, что потом все программы будут корректно работать с файлом, который был создан таким способом. Да и не во всех случаях этот способ работает.
Таким образом, преобразование файла из формата Excel в XML будет совершено.
Способ 2: инструменты разработчика
Конвертировать формат Excel в XML можно с помощью инструментов разработчика на вкладке программы. При этом, если пользователь все выполнит правильно, то на выходе он получит, в отличие от предыдущего способа, полноценный XML-файл, который корректно будет восприниматься сторонними приложениями. Но сразу нужно сказать, что не каждому новичку может хватить знаний и умений сразу научится конвертировать данные таким способом.
- По умолчанию вкладка инструментов разработчика отключена. Поэтому, прежде всего, нужно её активировать. Переходим во вкладку «Файл» и кликаем по пункту «Параметры» .
- В открывшемся окне параметров перемещаемся в подраздел «Настройка ленты» . В правой части окна устанавливаем галочку около значения «Разработчик» . После этого жмем на кнопку «OK» , размещенную в нижней части окна. Вкладка инструментов разработчика теперь включена.
- Далее открываем таблицу Excel в программе любым удобным способом.
- На её основе нам предстоит создать схему, которая формируется в любом текстовом редакторе. Для этих целей можно использовать и обычный Блокнот Windows, но лучше применять специализированное приложение для программирования и работы с языками разметки . Запускаем эту программу. В ней создаем схему. На нашем примере она будет выглядеть, как показано внизу на скриншоте окна Notepad++.
Как видим, открывающим и закрывающим тегом для документа в целом служит «data-set» . В этой же роли для каждой строки выступает тег «record» . Для схемы вполне будет достаточно, если мы возьмем всего две строки таблицы, а не будем переводить её всю вручную в XML. Название открывающего и закрывающего тега столбца может быть произвольным, но в данном случае для удобства мы предпочли просто перевести русскоязычные наименования колонок на английский язык. После того, как данные внесены, просто сохраняем их через функционал текстового редактора в любом месте на жестком диске в формате XML под названием «schema» .
- Опять переходим к программе Excel с уже открытой таблицей. Перемещаемся во вкладку «Разработчик» . На ленте в блоке инструментов «XML» кликаем по кнопке «Источник» . В открывшемся поле в левой части окна жмем на кнопку «Карты XML…» .
- В открывшемся окне кликаем по кнопке «Добавить…» .
- Запускается окно выбора источника. Переходим в директорию расположения схемы составленной ранее, выбираем её и кликаем по кнопке «Открыть» .
- После того, как элементы схемы появились в окне, перетаскиваем их с помощью курсора в соответствующие ячейки наименования столбцов таблицы.
- Кликаем правой кнопкой мыши по полученной таблице. В контекстном меню последовательно переходим по пунктам «XML» и «Экспорт…» . После этого сохраняем файл в любой директории.
Как видим, существуют два основных способа конвертации файлов XLS и XLSX в формат XML программой Microsoft Excel. Первый из них предельно простой и заключается в элементарной процедуре сохранения с заданным расширением через функцию «Сохранить как…» . Простота и понятность данного варианта, несомненно, являются преимуществами. Но у него есть один очень серьезный недостаток. Преобразование выполняется без учета определенных стандартов, и поэтому файл, конвертируемый таким способом, сторонними приложениями может просто не распознаваться. Второй вариант предполагает составление карты XML. В отличие от первого способа, таблица, преобразованная по данной схеме, будет соответствовать всем стандартам качества XML. Но, к сожалению, не каждый пользователь сможет быстро разобраться с нюансами этой процедуры.