Библиотека MS XML Parser предоставляет возможность работы с XML-документами в скриптах, использующих объектную модель DOM XML. Такая работа возможна практически в любых средах, способных выступить в роли OLE-клиента. В данной статье примеры скриптов будут приводиться на языке VBScript для административных скриптов Windows. Вы можете копировать содержимое подобных примеров в текстовые файлы с расширением .vbs и запускать эти файлы на исполнение двойным щелчком мыши или из командной строки с помощью интерпретатора cscript.exe.
Объект DOMDocument создаётся следующим образом:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
После этого вы можете вызывать и использовать методы и свойства этого объекта для чтения и записи XML-документов. Примечание: методы объектов XMLDOMDocument и XMLDOMElement во многом сходны, поэтому рассматриваются в данной статье совместно. Описание свойств, методов и событий в данной статье не является полностью исчерпывающим. Полное описание объектной модели MS XML Parser вы можете получить в MSDN, воспользовавшись, например, поиском по словосочетанию "IXMLDOMDocument/DOMDocument Members" или "IXMLDOMElement Members".
В примерах кода, приведённых ниже, используется следующий "образцовый" XML-документ, представляющий из себя некий
абстрактный упрощённый каталог товаров:
<?xml version="1.0"?>
<!DOCTYPE PRODUCTS
[
<!ELEMENT PRODUCTS (PRODUCT)*>
<!ELEMENT PRODUCT (TITLE, SORT+)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT COLOR (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>
<!ELEMENT SORT (COLOR, PRICE)>
<!ATTLIST PRODUCT import (yes | no) "no">
]
>
<PRODUCTS>
<PRODUCT import="yes">
<TITLE> Product #1 </TITLE>
<SORT>
<COLOR> red </COLOR>
<PRICE> $10.00 </PRICE>
</SORT>
<SORT>
<COLOR> blue </COLOR>
<PRICE> $11.00 </PRICE>
</SORT>
<SORT>
<COLOR> gray </COLOR>
<PRICE> $16.00 </PRICE>
</SORT>
</PRODUCT>
<PRODUCT>
<TITLE> Product #2 </TITLE>
<SORT>
<COLOR> red </COLOR>
<PRICE> $20.00 </PRICE>
</SORT>
<SORT>
<COLOR> green </COLOR>
<PRICE> $22.00 </PRICE>
</SORT>
</PRODUCT>
<PRODUCT import="yes">
<TITLE> Product #3 </TITLE>
<SORT>
<COLOR> red </COLOR>
<PRICE> $30.00 </PRICE>
</SORT>
<SORT>
<COLOR> blue </COLOR>
<PRICE> $33.00 </PRICE>
</SORT>
</PRODUCT>
<PRODUCT>
<TITLE> Product #4 </TITLE>
<SORT>
<COLOR> red </COLOR>
<PRICE> $40.00 </PRICE>
</SORT>
<SORT>
<COLOR> blue </COLOR>
<PRICE> $44.00 </PRICE>
</SORT>
</PRODUCT>
<PRODUCT>
<TITLE> Product #5 </TITLE>
<SORT>
<COLOR> red </COLOR>
<PRICE> $50.00 </PRICE>
</SORT>
<SORT>
<COLOR> gray </COLOR>
<PRICE> $55.00 </PRICE>
</SORT>
</PRODUCT>
</PRODUCTS>
Вот XSL-таблица стилей для вышеприведённого документа, которая также является обычным XML-документом:
<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<H1>Каталог товаров</H1>
<xsl:apply-templates select="PRODUCTS/PRODUCT" />
</xsl:template>
<xsl:template match="PRODUCT">
<SPAN style="font-style:italic">Наименование:</SPAN>
<xsl:value-of select="TITLE" /> <BR />
<SPAN style="font-style:italic">Импортный:</SPAN>
<xsl:value-of select="@import" /> <BR />
<TABLE border="1" width="100%" cellspacing="0">
<xsl:apply-templates select="SORT" />
</TABLE>
<BR />
</xsl:template>
<xsl:template match="SORT">
<TR>
<TD><xsl:value-of select="COLOR" /></TD>
<TD><xsl:value-of select="PRICE" /></TD>
</TR>
</xsl:template>
</xsl:stylesheet>
Перечень свойств, методов и событий:
Описание | |
---|---|
async | Булево. Чтение и запись. Истина, если разрешена асинхронная загрузка документа. По умолчанию - истина. Если свойство установлено в True, метод load вернёт управление раньше, чем загрузка будет завершена. В этом случае вы можете использовать свойство readyState для проверки состояния загрузки, обрабатывая событие onreadystatechange. |
parsed | Булево. Только для чтения. Определяет состояние разборки узла и его дочерних узлов. В процессе асинхронного доступа в какой-то конкретный момент может оказаться доступным не все дерево документа. Перед выполнением некоторых операций, типа преобразований XSLT, полезно знать, доступно ли все дерево ниже этого узла для обработки. |
parseError | Только для чтения. Возвращает ссылку на объект XMLDOMParseError, при помощи которого можно получить подробную информацию о последней ошибке анализатора. |
readyState | Только для чтения. Возвращает целое число, характеризующее текущее состояние анализатора:
|
resolveExternals | Булево. Чтение и запись. По умолчанию - истина. Определяет, должны ли быть разрешены во время разбора внешние определения - пространства имён, внешние подмножества DTD и ссылки на внешние примитивы, независимо от проверки на валидность. Если задано True, внешние определения разрешаются во время разбора. Это позволяет определить атрибуты по умолчанию и типы данных и использовать внешнее подмножество DTD. Эта установка независима от того, должна ли быть выполнена проверка на валидность (что задаётся значением свойства validateOnParse). Если внешнее определение не может быть разрешено в процессе разбора, происходит ошибка. |
validateOnParse | Булево. Чтение и запись. По умолчанию - истина. Определяет, должен ли парсер проверить документ на валидность. Если установлено False, осуществляется только проверка на корректно сформированный (well-formed) документ. |
abort() | Прерывание процесса асинхронной загрузки и обработки документа. Объект XMLDOMParseError будет содержать информацию об ошибке. Если загрузка уже завершена (свойство readyState равно 4), никакие действия не предпринимаются. |
load(xmlSource) | Загружает документ, URL которого задан параметром xmlSource. В случае успеха возвращает True. Вызов этого метода обнуляет содержимое текущего документа. Если указанный URL не доступен или не ссылается на документ XML, этот метод возвращает ошибку и устанавливает свойство documentElement в null. Вы можете использовать этот метод, чтобы проверить, правильно ли построен (well-formed) документ XML. Вы не можете использовать этот метод, чтобы проверить документ на валидность. |
loadXML(strXML) | Загружает XML-фрагмент из передаваемой строки. Вы можете использовать этот метод, чтобы проверить, правильно ли построен (well-formed) документ XML. Вы не можете использовать этот метод, чтобы проверить документ на валидность. |
ondataavailable | Событие вызывается, когда обработчик обрабатывает очередную порцию данных документа. В обработчике этого события можно проверять текущий статус асинхронной загрузки (значение свойства readyState). |
onreadystatechange | Событие вызывается каждый раз, когда изменяется состояние обработчика - значение свойства readyState. |
Свойства объекта XMLDOMParseError (все свойства доступны только для чтения):
Описание | |
---|---|
errorCode | Содержит код возникшей ошибки или нуль, если ошибки не случилось. |
filepos | Содержит смещение относительно начала файла, в котором обнаружена ошибка. |
line | Содержит номер строки, в которой обнаружена ошибка. |
linepos | Содержит позицию ошибки в строке, в которой обнаружена ошибка. |
reason | Содержит описание ошибки. |
srcText | Содержит полный текст строки, в которой обнаружена ошибка. |
url | Содержит URL обрабатываемого документа. |
Пример скрипта, осуществляющего загрузку XML-документа с проверкой на ошибки:
'Создаём OLE-объект DOMDocument
Set xmlParser = CreateObject("Msxml2.DOMDocument")
'Отключаем асинхронную загрузку
xmlParser.async = False
'Загружаем XML-документ
xmlParser.load "C:\Sample.xml"
'Если случилась ошибка, выдаём информацию о ней и завершаем работу
If xmlParser.parseError.errorCode Then
ShowError xmlParser.parseError
WScript.Quit
End If
'Выводим содержимое XML-документа
WScript.Echo xmlParser.xml
'Освобождаем объектную переменную
Set xmlParser = Nothing
'******************************************************************************
Function ShowError(XMLDOMParseError)
mess = _
"parseError.errorCode: " & XMLDOMParseError.errorCode & vbCrLf & _
"parseError.filepos: " & XMLDOMParseError.filepos & vbCrLf & _
"parseError.line: " & XMLDOMParseError.line & vbCrLf & _
"parseError.linepos: " & XMLDOMParseError.linepos & vbCrLf & _
"parseError.reason: " & XMLDOMParseError.reason & vbCrLf & _
"parseError.srcText: " & XMLDOMParseError.srcText & vbCrLf & _
"parseError.url: " & XMLDOMParseError.url & vbCrLf
WScript.Echo mess
End Function
Пример асинхронной загрузки XML-документа:
Set xmlParser = WScript.CreateObject("Msxml2.DOMDocument","xmlParser_")
xmlParser.load "C:\Sample.xml"
'******************************************************************************
Function xmlParser_onreadystatechange()
WScript.Echo "readyState = " & xmlParser.readyState
If xmlParser.readyState = 4 Then
WScript.Echo xmlParser.xml
End If
End Function
Перечень свойств и методов:
Описание | |
---|---|
documentElement | Содержит узел, представляющий корневой элемент документа (объект XMLDOMElement). Чтение и запись. Возможно присвоение ссылки на другой объект созданного ранее документа. |
childNodes | Содержит коллекцию (объект XMLDOMNodeList) всех дочерних узлов-неатрибутов данного узла. Только чтение. |
firstChild | Содержит первый дочерний узел данного узла, не являющийся атрибутом. Только чтение. |
lastChild | Содержит последний дочерний узел данного узла, не являющийся атрибутом. Только чтение. |
nextSibling | Содержит следующий узел (любого типа) на том же уровне данного узла. Только чтение. |
previousSibling | Содержит предыдущий узел (любого типа) на том же уровне данного узла. Только чтение. |
parentNode | Содержит узел, для которого данный узел является дочерним (не действует для атрибутов). Только чтение. |
ownerDocument | Содержит корневой узел документа, содержащего данный узел. Только чтение. |
text | Содержит всё текстовое содержимое данного узла, включая подчинённые узлы. Чтение и запись. |
xml | Содержит всё xml-содержимое данного узла, включая подчинённые узлы. Только чтение. |
nodeValue | Содержит значение данного узла. Если компонент XML непосредственно не имеет значения, содержит null. Чтение и запись. |
getElementsByTagName(typename) | Возвращает коллекцию XMLDOMNodeList всех элементов заданного типа. Если указано "*", возвращает все элементы. |
attributes | Содержит коллекцию XMLDOMNamedNodeMap всех дочерних узлов-атрибутов данного узла. Только чтение. |
getAttribute(name) | Возвращает значение атрибута с заданным именем. |
getAttributeNode(name) | Возвращает узел атрибута с заданным именем. |
Описание | |
---|---|
length | Количество элементов (узлов) в коллекции. |
item(index) | Возвращает узел по заданному индексу. Отсчёт начинается с нуля. Данный метод является методом по умолчанию. |
reset() | Устанавливает внутренний указатель на позицию перед первым узлом в наборе, чтобы следующий вызов nextNode() возвращал первый узел. |
nextNode() | Возвращает следующий узел в наборе, в соответствии с позицией внутреннего указателя. |
Описание | |
---|---|
getNamedItem(strName) | Возвращает узел, соответствующий атрибуту с заданным именем. |
setNamedItem(newItem) | Добавляет переданный узел-атрибут в коллекцию (если атрибут с таким именем уже есть, замещает). |
Описание | |
---|---|
nodeName | Содержит полное имя данного узла, включая префикс пространства имён. Только чтение. |
baseName | Содержит имя данного узла без префикса пространства имён. Только чтение. |
prefix | Содержит префикс (пространства имён) имени данного узла. Только чтение. |
nodeType | Содержит тип текущего узла (число). Только чтение. Возможные значения:
|
nodeTypeString | Содержит тип текущего узла (строка строчными буквами). Только чтение. |
dataType | Содержит тип данных узла-атрибута, если этот тип данных определён в DTD. Чтение и запись. |
namespaceURI | Содержит URI пространства имён текущего узла. Только чтение. |
definition | Для узла типа "entityreference" содержит узел типа "entity" (т.е. его DTD-определение). Только чтение. |
Рекурсивный обход всего дерева элементов с выводом информации о текущем узле. Этот скрипт будет работать для любого
XML-документа, в т.ч. для XSL-таблицы стилей, приведённой выше непосредственно после нашего "каталога товаров":
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Запускаем рекурсию с корневого элемента (нулевой уровень)
ParseNode xmlParser.documentElement, 0
'******************************************************************************
Function ParseNode(nodeNode, numLevel)
'Выводим данные об узле
WScript.Echo Space(numLevel*4) & nodeNode.nodeName & _
" (baseName = " & nodeNode.baseName & "," & _
" prefix = " & nodeNode.prefix & ")"
WScript.Echo Space(numLevel*4) & "(nodeType = " & nodeNode.nodeType & "," & _
" nodeTypeString = " & nodeNode.nodeTypeString & ")"
WScript.Echo Space(numLevel*4) & "(dataType = " & nodeNode.dataType & "," & _
" namespaceURI = " & nodeNode.namespaceURI & ")"
'Выводим рекурсивно атрибуты узла, если они есть
If Not nodeNode.attributes Is Nothing Then
For Each nodeChild In nodeNode.attributes
ParseNode nodeChild, numLevel+1
Next
End If
'Выводим рекурсивно дочерние узлы, если они есть
If nodeNode.childNodes.length > 0 Then
For Each nodeChild In nodeNode.childNodes
ParseNode nodeChild, numLevel+1
Next
End If
End Function
Перечень методов:
Описание | |
---|---|
selectNodes(patternString) | Возвращает коллекцию XMLDOMNodeList, содержащую поддерево, выбранное по шаблону поиска patternString. |
selectSingleNode(patternString) | Аналогичен методу selectNodes, но возвращает только первый узел из выбранного поддерева. |
В качестве параметра вышеуказанные методы принимают строку XSL-запроса (образец поиска - XSL pattern). Язык XSL-запросов напоминает способ определения пути в файловой системе - это список узлов, разделённых символом "/". Для указания на текущий элемент используется символ ".", на родительский - "..", для указания на все дочерние элементы - символ "*", для указания на элемент, расположенный ниже по дереву (не важно, на каком уровне вложенности) - символы "//". Условия в запросе заключаются в квадратные скобки "[" и "]". Имена атрибутов в запросе должны предваряться символом "@".
Вот примеры простейших запросов к образцовому XML-документу, расположенному в начале статьи:
Выберем из образцового XML-документа и отобразим наименования отечественных товаров, у которых есть сорт серого
цвета, а также всех импортных товаров:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Выбираем заголовки (элементы TITLE) тех товаров,
'которые отвечают заданным условиям
Set colNodes = _
xmlParser.selectNodes("//PRODUCT[(@import='no' and SORT/COLOR = 'gray')" & _
" or (@import='yes')]/TITLE")
'Перебираем полученную выборку
For Each nodeNode In colNodes
WScript.Echo nodeNode.text
Next
Вот запрос, составленный по-другому, но возвращающий те же результаты:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Выбираем заголовки (элементы TITLE) тех товаров,
'которые отвечают заданным условиям
Set colNodes = _
xmlParser.selectNodes("//TITLE[(../@import='no' and ../SORT/COLOR='gray')" & _
" or (../@import='yes')]")
'Перебираем полученную выборку
For Each nodeNode In colNodes
WScript.Echo nodeNode.text
Next
Ещё один способ выборки, с использованием метода selectSingleNode:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Выбираем товары, которые отвечают заданным условиям
Set colNodes = _
xmlParser.selectNodes("//PRODUCT[(@import='no' and SORT/COLOR = 'gray')" & _
" or (@import='yes')]")
'Перебираем полученную выборку
For Each nodeNode In colNodes
Set nodeTitle = nodeNode.selectSingleNode("TITLE")
WScript.Echo nodeTitle.text
Next
Перечень методов:
Описание | |
---|---|
save(objTarget) | Сохраняет документ в файле (если указан URL) или замещает содержимое другого документа (если указан объект XMLDOMDocument). |
createElement(tagName) | Создаёт и возвращает элемент с указанным именем. |
createAttribute(name) | Создаёт и возвращает новый атрибут с указанным именем. |
createCDATASection(strData) | Создаёт и возвращает новый узел CDATA, содержащий переданное значение. |
createProcessingInstruction(strTarget, strData) | Создаёт и возвращает новый узел инструкции по обработке. |
createComment(strComment) | Создаёт и возвращает новый узел комментария. |
createEntityReference(strName) | Создаёт и возвращает новый узел ссылки на примитив. |
createTextNode(strText) | Создаёт и возвращает новый текстовый узел. |
createNode(numType, strName, strNamespaceURI) | Универсальный метод - создаёт и возвращает новый узел указанного типа и названия. Позволяет использовать пространства имён. |
createDocumentFragment() | Создаёт и возвращает новый пустой фрагмент XML-документа, который в дальнейшем можно "наполнить" узлами и присоединить к XML-документу. |
cloneNode(boolDeep) | Создаёт и возвращает копию текущего узла. Параметр boolDeep определяет, нужно ли рекурсивно копировать дочерние элементы. |
setAttribute(name, value) | Устанавливает значение указанного атрибута текущего узла. При необходимости создаёт атрибут. |
setAttributeNode(AttributeNode) | Устанавливает или обновляет переданный атрибут у текущего элемента. |
removeAttribute(name) | Удаляет указанный атрибут. Если указанный атрибут имеет значение по умолчанию, вместо удаления происходит замещение: атрибуту просто устанавливается значение по умолчанию. |
removeAttributeNode(nodeAttribute) | Удаляет переданный объект узла-атрибута. Если этот атрибут имеет значение по умолчанию, вместо удаления происходит замещение: атрибуту просто устанавливается значение по умолчанию. |
appendChild(newChildNode) | Добавляет текущему узлу новый дочерний элемент и возвращает ссылку на этот элемент. То же самое можно сделать вызовом insertBefore(newChildNode, null). |
insertBefore(newChildNode, refChildNode) | Вставляет новый дочерний узел (newChildNode) перед указанным существующим дочерним узлом (refChildNode). Если последний параметр не задан, новый дочерний узел будет добавлен в конец. |
replaceChild(newChildNode, oldChildNode) | Заменяет указанный дочерний объект текущего элемента на новый и возвращает старый дочерний объект. Если новый дочерний объект - null, старый дочерний объект будет просто удалён. |
removeChild(childNode) | Удаляет указанный дочерний объект текущего элемента и возвращает его. |
Все методы, которые создают новые объекты (createElement, createAttribute и подобные) не выполняют никакой работы, кроме непосредственно самого создания объектов. Для включения созданных объектов в документ надо дополнительно вызывать методы appendChild, insertBefore и подобные.
Пример создания нового XML-документа:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
'Создание объявления XML
xmlParser.appendChild(xmlParser.createProcessingInstruction("xml", "version='1.0' encoding='windows-1251'"))
'Создание комментария
xmlParser.appendChild(xmlParser.createComment("Текст комментария"))
'Создание корневого элемента
Set rootNode = xmlParser.appendChild(xmlParser.createElement("ROOT"))
'Создание первого вложенного элемента
Set subNode = rootNode.appendChild(xmlParser.createElement("SUB"))
subNode.text = "Текст первого вложенного элемента"
'Создание второго вложенного элемента
Set subNode = rootNode.appendChild(xmlParser.createElement("SUB"))
'Создание раздела CDATA
subNode.appendChild(xmlParser.createCDATASection("<<< >>> &&& Произвольные текстовые данные"))
'Создание ссылки на примитив
subNode.appendChild(xmlParser.createEntityReference("amp"))
'Создание текстового узла
subNode.appendChild(xmlParser.createTextNode("Текст второго вложенного элемента"))
'Создание третьего вложенного элемента с использованием пространства имён
Set subNode = rootNode.appendChild(xmlParser.createNode(1, "html:H1", "http://www.w3c.org/TR/REC-html40/"))
subNode.text = "Заголовок HTML"
'Создание четвёртого и пятого вложенных элементов с использованием фрагмента
Set Fragment = xmlParser.createDocumentFragment
Fragment.appendChild(xmlParser.createElement("SUB"))
Fragment.appendChild(xmlParser.createElement("SUB"))
rootNode.appendChild(Fragment)
xmlParser.save("C:\Test.xml")
Добавим новый товар в начало нашего существующего "каталога товаров":
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Получаем корневой элемент
Set rootPRODUCTS = xmlParser.documentElement
'Получаем первый товар
Set firstPRODUCT = xmlParser.documentElement.childNodes(0)
'Вставляем новый товар перед первым
Set newPRODUCT = rootPRODUCTS.insertBefore(xmlParser.createElement("PRODUCT"), firstPRODUCT)
'Устанавливаем атрибут "import" для нового товара
Set newAttr = xmlParser.createAttribute("import")
newAttr.value = "yes"
newPRODUCT.setAttributeNode(newAttr)
'Добавляем наименование новому товару
Set newTITLE = newPRODUCT.appendChild(xmlParser.createElement("TITLE"))
newTITLE.text = "Product #0"
'Добавляем сорт новому товару
Set newSORT = newPRODUCT.appendChild(xmlParser.createElement("SORT"))
'Добавляем цвет сорту
Set newCOLOR = newSORT.appendChild(xmlParser.createElement("COLOR"))
newCOLOR.text = "navy"
'Добавляем цену сорту
Set newPRICE = newSORT.appendChild(xmlParser.createElement("PRICE"))
newPRICE.text = "$0.01"
'Сохраняем весь документ
xmlParser.save("C:\Sample.xml")
Добавим новый товар в начало нашего существующего "каталога товаров" с помощью копирования:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Получаем корневой элемент
Set rootPRODUCTS = xmlParser.documentElement
'Получаем первый товар
Set firstPRODUCT = xmlParser.documentElement.childNodes(0)
'Вставляем копию первого товара перед первым товаром
Set newPRODUCT = rootPRODUCTS.insertBefore(firstPRODUCT.cloneNode(True), firstPRODUCT)
'Устанавливаем атрибут "import" для нового товара
newPRODUCT.setAttribute "import", "yes"
'Сохраняем документ
xmlParser.save("C:\Test.xml")
Меняем местами, удаляем товары:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Получаем корневой элемент
Set rootPRODUCTS = xmlParser.documentElement
'Получаем копии первого и второго товаров
Set firstPRODUCT = rootPRODUCTS.childNodes(0).cloneNode(True)
Set secondPRODUCT = rootPRODUCTS.childNodes(1).cloneNode(True)
'Меняем местами первый и второй товары
rootPRODUCTS.replaceChild secondPRODUCT, rootPRODUCTS.childNodes(0)
rootPRODUCTS.replaceChild firstPRODUCT, rootPRODUCTS.childNodes(1)
'Удаляем последний товар
rootPRODUCTS.removeChild rootPRODUCTS.lastChild
'Сохраняем документ
xmlParser.save("C:\Test.xml")
Перечень методов:
Описание | |
---|---|
transformNode(objStylesheet) | Назначает стилевую таблицу для текущего узла и возвращает строку - результат обработки. Текущим узлом может быть весь XML-документ. |
transformNodeToObject(objStylesheet, objXMLDOMDocument) | То же, что и transformNode, но результат не возвращается, а помещается в objXMLDOMDocument. |
Применяем существующую стилевую таблицу к каталогу товаров:
'Загружаем документ
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Загружаем стилевую таблицу
Set objStylesheet = CreateObject("Msxml2.DOMDocument")
objStylesheet.async = False
objStylesheet.load "C:\Sample.xsl"
'Применяем стилевую таблицу к документу
WScript.Echo xmlParser.transformNode(objStylesheet)
Вывод товаров в обратном порядке с помощью XSL-сортировки:
'Загружаем документ
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Загружаем стилевую таблицу
Set objStylesheet = CreateObject("Msxml2.DOMDocument")
objStylesheet.async = False
objStylesheet.loadXML _
"<?xml version='1.0' encoding='windows-1251'?>" & _
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/TR/WD-xsl'>" & _
vbCrLf & _
"<xsl:template match='/'>" & _
"<PRODUCTS>" & _
"<xsl:apply-templates select='PRODUCTS/PRODUCT' order-by='-TITLE' />" & _
"</PRODUCTS>" & _
"</xsl:template>" & _
vbCrLf & _
"<xsl:template match='PRODUCT'>" & _
"<PRODUCT>" & _
"<xsl:value-of select='TITLE' />" & _
"</PRODUCT>" & _
"</xsl:template>" & _
vbCrLf & _
"</xsl:stylesheet>"
'Применяем стилевую таблицу к документу
Set objResult = CreateObject("Msxml2.DOMDocument")
objResult.async = False
xmlParser.transformNodeToObject objStylesheet, objResult
'Выводим результаты
For Each nodeNode In objResult.documentElement.childNodes
WScript.Echo nodeNode.text
Next
Перечень свойств и методов:
Описание | |
---|---|
doctype | Содержит объект XMLDOMDocumentType (узел DTD XML-документа). Только чтение. Если DTD в документе отсутствует, свойство содержит null. Только чтение. |
url | Содержит URL документа. Только чтение. |
nodeFromID(idString) | Возвращает узел по значению его атрибута типа ID (т.е. осуществляет поиск узла по ID) или Nothing, если узел не найден. |
hasChildNodes() | Возвращает True, если текущий узел имеет дочерние узлы, и False в противном случае. |
specified | Возвращает True, если текущий узел атрибута явно определён в тексте документа, и False в противном случае (если атрибут опущен и имеет значение по умолчанию, взятое из DTD). |
normalize() | Нормализует все текстовые узлы элемента (на любой глубине), объединяя два или больше смежных текстовых узла в один текстовый узел. |
Примеры использования некоторых свойств и методов:
Set xmlParser = CreateObject("Msxml2.DOMDocument")
xmlParser.async = False
xmlParser.load "C:\Sample.xml"
'Отображаем DTD документа
WScript.Echo xmlParser.doctype.xml
'Отображаем URL документа
WScript.Echo xmlParser.url
'Проверяем, имеет ли корневой узел документа дочерние узлы
If xmlParser.documentElement.hasChildNodes Then
WScript.Echo "Узел " & xmlParser.documentElement.nodeName & " имеет дочерние узлы."
End If
'Проверяем, у каких товаров (элементов "PRODUCTS") явно задан атрибут "import"
For Each nodePRODUCT In xmlParser.documentElement.childNodes
strTitle = nodePRODUCT.getElementsByTagName("TITLE")(0).text
If nodePRODUCT.attributes(0).specified Then
WScript.Echo "У товара '" & strTitle & "' атрибут 'import' задан явно - " & _
nodePRODUCT.getAttribute("import")
Else
WScript.Echo "У товара '" & strTitle & "' атрибут 'import' опущен - " & _
nodePRODUCT.getAttribute("import")
End If
Next
Людоговский Александр
1. Электромагнитная волна (в религиозной терминологии релятивизма - "свет") имеет строго постоянную скорость 300 тыс.км/с, абсурдно не отсчитываемую ни от чего. Реально ЭМ-волны имеют разную скорость в веществе (например, ~200 тыс км/с в стекле и ~3 млн. км/с в поверхностных слоях металлов, разную скорость в эфире (см. статью "Температура эфира и красные смещения"), разную скорость для разных частот (см. статью "О скорости ЭМ-волн")
2. В релятивизме "свет" есть мифическое явление само по себе, а не физическая волна, являющаяся волнением определенной физической среды. Релятивистский "свет" - это волнение ничего в ничем. У него нет среды-носителя колебаний.
3. В релятивизме возможны манипуляции со временем (замедление), поэтому там нарушаются основополагающие для любой науки принцип причинности и принцип строгой логичности. В релятивизме при скорости света время останавливается (поэтому в нем абсурдно говорить о частоте фотона). В релятивизме возможны такие насилия над разумом, как утверждение о взаимном превышении возраста близнецов, движущихся с субсветовой скоростью, и прочие издевательства над логикой, присущие любой религии.
4. В гравитационном релятивизме (ОТО) вопреки наблюдаемым фактам утверждается об угловом отклонении ЭМ-волн в пустом пространстве под действием гравитации. Однако астрономам известно, что свет от затменных двойных звезд не подвержен такому отклонению, а те "подтверждающие теорию Эйнштейна факты", которые якобы наблюдались А. Эддингтоном в 1919 году в отношении Солнца, являются фальсификацией. Подробнее читайте в FAQ по эфирной физике.