Vamos a ver a continuación como se maneja el DOM (Document Object Model) implementado por el Microsoft XML Parser, a través de Visual Basic.
Aunque los detalles
puedan cambiar, la forma de trabajar va aser similiar para otros parsers en otras
plataformas de desarrollo (VC++, Java, etc.)
El parser o analizador de XML es el programa que lee el documento XML y hace que los datos que contiene estén accesibles de una manera u otra. Además, el parser puede tener otras funcionalidades, como validar el documento contra una DTD o un schema. El parser de Microsoft (msxml.dll), que se distribuye con el IE5, hace eso mismo, haciendo que los datos estén disponibles a través de una serie de objetos que el programador puede utilizar.
La especificación "DOM Level 1" en la que esta basada esta implementación se puede encontrar en http://www.w3.org/TR/REC-DOM-Level-1
Este parser podemos utilizarlo tanto en programas VBScript que se ejecuten en un servidor web (ASP, Active Server Pages) o en un programa Visual Basic. Por ejemplo, para crear una instancia del parser en un ASP, hacemos lo siguiente:
Set objParser = Server.CreateObject("Microsoft.XMLDOM")
Para utilizarlo en Visual Basic, tenemos que añadir el objeto COM Microsoft XML, version 2.0, en las referencias del proyecto, y luego crear una instancia del objeto:
Dim objParser As MSXML.DOMDocument
Set objParser = New MSXML.DOMDocument
Para cargar un documento XML, usamos el método .Load del objeto, especificando la ruta del documento, o bien mediante un URL que indique dónde se encuentra en la red.
If objParser.Load("c:\temp\xml\documento.xml") Then
' Ha funcionado
Else
' Ha ocurrido un error
End If
' Ahora destruimos el objeto parser
Set objParser = nothing
El método .Load puede fallar porque el nombre o ubicación del documento sea erronea, o bien porque el documento es inválido (no cumple las condiciones impuestas en su DTD o schema)
La validación del documento se puede suprimir si hacemos lo siguiente antes de cargar el documento:
objParser.validateOnParse = False
Una vez cargado, analizado y validado el documento, podemos empezar a utilizar la información que contiene. Para eso utilizamos la interface IXMLDOMNode del parser, que nos permite acceder a los diferentes nodos (elementos, atributos, texto, etc.) del documento.
Este interface nos provee de ciertos métodos y propiedades para acceder con comodidad a los contenidos del documento, tanto para lectura como para escritura.
nodeType
Nos da información sobre el tipo de un nodo. Este parser soporta 13 tipos diferentes de nodo. (Están marcados en negrita los que más se usan)
nodeName
Si el tipo de nodo es adecuado, nodeName nos devuelve el nombre del nodo. Por ejemplo un nodo tipo NODE_ELEMENT contendría en nodeName el nombre de un elemento de un documento XML.
nodeValue
Nos devuelve el valor que contiene ese nodo, si es aplicable. childNodes
Contiene una colección de nodos "hijos" del nodo que estamos considerando. Esta colección puede ser iterada por una construcción for each de Visual Basic.
hasChildNodes
Propiedad booleana que nos dice si un nodo tiene "hijos".
firstChild / lastChild
Contienen referencias al primer y último "hijos" de un nodo.
parentNode
Nos devuelve una referencia al "padre" del nodo.
nextSibling / previousSibling
Nos devuelve una referencia al siguiente/anterior "hermano" del nodo, es decir, al siguiente/anterior nodo con el mismo "padre".
attributes
Nos devuelve una colección de los nodos tipo NODE_ATTRIBUTE del nodo.
Vamos a ver un ejemplo de un sencillo programa que selecciona todos los nodos tipo texto (NODE_TEXT) de un documento XML de una forma recursiva.
Public Sub CargaDoc()
Dim oParser As MSXML.DOMDocument
Set oParser = New MSXML.DOMDocument
If oParser.Load("test.xml") Then
MuestraNodos oParser.childNodes
Else
MsgBox "Ha ocurrido un error."
End If
End Sub
Public Sub MuestraNodos(ByRef Nodos As MSXML.IXMLDOMNodeList)
Dim oNodo As MSXML.IXMLDOMNode
For Each oNodo In Nodos
If oNodo.nodeType = NODE_TEXT Then
Debug.Print oNodo.parentNode.nodeName & "=" & oNodo.nodeValue
End If
If oNodo.hasChildNodes Then
MuestraNodos oNodo.childNodes
End If
Next oNodo
End Sub
Si el fichero test.xml que usa este programa fuera el siguiente:
<?xml version="1.0"?>
<documento>
<titulo>Un documento cualquiera</titulo>
<fecha><dia>1</dia><mes>12</mes><año>1999</año></fecha>
</documento>
El resultado sería:
titulo=Un documento cualquiera
dia=1
mes=12
año=1999
Para más información sobre el parser MSXML, visita el MSDN Online XML Developer Center
El parser o analizador de XML es el programa que lee el documento XML y hace que los datos que contiene estén accesibles de una manera u otra. Además, el parser puede tener otras funcionalidades, como validar el documento contra una DTD o un schema. El parser de Microsoft (msxml.dll), que se distribuye con el IE5, hace eso mismo, haciendo que los datos estén disponibles a través de una serie de objetos que el programador puede utilizar.
La especificación "DOM Level 1" en la que esta basada esta implementación se puede encontrar en http://www.w3.org/TR/REC-DOM-Level-1
Este parser podemos utilizarlo tanto en programas VBScript que se ejecuten en un servidor web (ASP, Active Server Pages) o en un programa Visual Basic. Por ejemplo, para crear una instancia del parser en un ASP, hacemos lo siguiente:
Set objParser = Server.CreateObject("Microsoft.XMLDOM")
Para utilizarlo en Visual Basic, tenemos que añadir el objeto COM Microsoft XML, version 2.0, en las referencias del proyecto, y luego crear una instancia del objeto:
Dim objParser As MSXML.DOMDocument
Set objParser = New MSXML.DOMDocument
Para cargar un documento XML, usamos el método .Load del objeto, especificando la ruta del documento, o bien mediante un URL que indique dónde se encuentra en la red.
If objParser.Load("c:\temp\xml\documento.xml") Then
' Ha funcionado
Else
' Ha ocurrido un error
End If
' Ahora destruimos el objeto parser
Set objParser = nothing
El método .Load puede fallar porque el nombre o ubicación del documento sea erronea, o bien porque el documento es inválido (no cumple las condiciones impuestas en su DTD o schema)
La validación del documento se puede suprimir si hacemos lo siguiente antes de cargar el documento:
objParser.validateOnParse = False
Una vez cargado, analizado y validado el documento, podemos empezar a utilizar la información que contiene. Para eso utilizamos la interface IXMLDOMNode del parser, que nos permite acceder a los diferentes nodos (elementos, atributos, texto, etc.) del documento.
Este interface nos provee de ciertos métodos y propiedades para acceder con comodidad a los contenidos del documento, tanto para lectura como para escritura.
nodeType
Nos da información sobre el tipo de un nodo. Este parser soporta 13 tipos diferentes de nodo. (Están marcados en negrita los que más se usan)
Constantes de tipos de nodo |
NODE_ATTRIBUTE |
NODE_CDATA_SECTION |
NODE_COMMENT |
NODE_DOCUMENT |
NODE_DOCUMENT_FRAGMENT |
NODE_DOCUMENT_TYPE |
NODE_ELEMENT |
NODE_ENTITY |
NODE_ENTITY_REFERENCE |
NODE_INVALID |
NODE_NOTATION |
NODE_PROCESSING_INSTRUCTION |
NODE_TEXT |
nodeName
Si el tipo de nodo es adecuado, nodeName nos devuelve el nombre del nodo. Por ejemplo un nodo tipo NODE_ELEMENT contendría en nodeName el nombre de un elemento de un documento XML.
nodeValue
Nos devuelve el valor que contiene ese nodo, si es aplicable. childNodes
Contiene una colección de nodos "hijos" del nodo que estamos considerando. Esta colección puede ser iterada por una construcción for each de Visual Basic.
hasChildNodes
Propiedad booleana que nos dice si un nodo tiene "hijos".
firstChild / lastChild
Contienen referencias al primer y último "hijos" de un nodo.
parentNode
Nos devuelve una referencia al "padre" del nodo.
nextSibling / previousSibling
Nos devuelve una referencia al siguiente/anterior "hermano" del nodo, es decir, al siguiente/anterior nodo con el mismo "padre".
attributes
Nos devuelve una colección de los nodos tipo NODE_ATTRIBUTE del nodo.
Vamos a ver un ejemplo de un sencillo programa que selecciona todos los nodos tipo texto (NODE_TEXT) de un documento XML de una forma recursiva.
Public Sub CargaDoc()
Dim oParser As MSXML.DOMDocument
Set oParser = New MSXML.DOMDocument
If oParser.Load("test.xml") Then
MuestraNodos oParser.childNodes
Else
MsgBox "Ha ocurrido un error."
End If
End Sub
Public Sub MuestraNodos(ByRef Nodos As MSXML.IXMLDOMNodeList)
Dim oNodo As MSXML.IXMLDOMNode
For Each oNodo In Nodos
If oNodo.nodeType = NODE_TEXT Then
Debug.Print oNodo.parentNode.nodeName & "=" & oNodo.nodeValue
End If
If oNodo.hasChildNodes Then
MuestraNodos oNodo.childNodes
End If
Next oNodo
End Sub
Si el fichero test.xml que usa este programa fuera el siguiente:
<?xml version="1.0"?>
<documento>
<titulo>Un documento cualquiera</titulo>
<fecha><dia>1</dia><mes>12</mes><año>1999</año></fecha>
</documento>
El resultado sería:
titulo=Un documento cualquiera
dia=1
mes=12
año=1999
Para más información sobre el parser MSXML, visita el MSDN Online XML Developer Center
Alfredo Reino Romero