
Buenos Aires, Argentina.
Ultima fecha de actualización, Agosto de 2001.
DOM, el Modelo de Objeto de Documento:
Existe un grupo de trabajo en la W3C encargado del Documento Object Model, es decir un modelo de objeto que permita manipular, agregar, eliminar y modificar cualquier tipo de elemento de un documento XML. La especificación tiene distintos niveles, el nivel uno cubre la manipulación de todo un documento XML, pero no de las DTDs ni de la aplicación de hojas de estilo ni tampoco espacios de nombres. El nivel dos describe acceso a las DTDs, a la aplicación de hojas de estilo y a los espacios de nombres, esta es la actual recomendación. El nivel tres está en desarrollo y está orientado a incorporar la tecnología XPath.
La especificación de DOM de W3C puede encontrarse en http://www.w3.org/TR/DOM-Level-1/, http://www.w3.org/TR/DOM-Level-2-Core/ y http://www.w3.org/TR/DOM-Level-3-Core/
Acá comienza la parte práctica de XML.
Interfaces DOM:
 |
DOMImplementation: Devuelve información sobre el nivel del DOM que soporta el objeto. |
 |
DocumentFragment: Devuelve información sobre un fragmento del documento. |
 |
Document: Proporciona información acerca del documento que el objeto haya cargado, tiene métodos para crear nodos y atributos. |
 |
Node: Todo en un documento es un nodo y esta interfaz proporciona métodos para manipular todo tipo de nodos. |
 |
NodeList: Es un conjunto ordenado de nodos. |
 |
NamedNodeMap: Es una colección de nodos a la que se puede acceder por nombre. |
 |
CharacterData: Es una interface que facilita el manejo de caracteres. |
 |
Attr: Se usa para manejar todo lo relacionado con atributos. |
 |
Element: Aquí hay un conjunto de métodos y propiedades para tratar elementos yatributos.
|
 |
Text: Es para tratar el contenido de texto de un elemento. |
 |
CDATASection |
 |
Notation |
 |
Entity |
 |
EntityReference |
 |
ProcessingInstruction |
Estas últimas cinco interfaces tratan nodos del tipo que su nombre indica.
Se puede recorrer el árbol DOM empezando por cualquier nodo y para moverse por él se puede usar los siguientes métodos de la interface Nodo:
 |
parentNode para acceder al nodo padre. |
 |
firstChild para acceder al primer nodo hijo. |
 |
nextSibling para acceder al siguiente nodo hermano. |
 |
previousSibling para acceder al nodo hermano previo. |
Pero si se desea acceder a un nodo por su nombre se puede usar getElementsByTagName, de esta forma se obtiene una lista de todos los nodos del documento cuyo nombre se haya especificado como argumento de getElementsByTagName.
Los métodos de las interfaces DOM devuelven los siguientes tipos de datos:
 |
unsigned short Entero corto sin signo. |
 |
unsigned long Entero largo sin signo. |
 |
Node Es un objeto que contiene todas las características del nodo. |
 |
NodeList Es una lista indexada de objetos nodo. |
 |
NamedNodeMap Es una lista no indexada de objetos nodo, en la práctica se usa para listas de nodos de atributo, entidad o notación. |
 |
DOMString Cadena de caracteres Unicode. |
 |
Boolean |
 |
Void Se usa cuando no se devuelve valor. |
Interfaz Document:
Devuelve información sobre el documento. Posee estos tres atributos de sólo lectura:
 |
doctype Devuelve la información del elemento <!DOCTYPE. En el nivel 1 del la especificación DOM no devuelve información acerca de la DTD. |
 |
implementation En el nivel 1 del DOM existe un método llamado hasFeatures() con dos parámetros, el tipo de documento, que puede ser XML o HTML y la versión |
 |
documentElement Devuelve el objeto de elemento raiz del documento. |
La interfaz posee los siguientes métodos:
 |
createElement |
 |
createDocumentFragment |
 |
createTextNode |
 |
createComment |
 |
createCDATASection |
 |
createProcessingInstruction |
 |
createAttribute |
 |
createEntityReference |
 |
getElementByTagName |
Todos los métodos que comienzan con create, crean nodos del tipo que se define en su propio nombre. Al crearse un nodo, este se encuentra aislado del árbol, es porque está faltando algún método de la interfaz Nodo, como insertBefore() o appendChild(). Se devuelve error si se usa un nombre XML no válido. CreateProcessingInstruction() tiene dos parámetros, el destino PI y los datos PI.
Interfaz DocumentFragment:
Sirve para trabajar con una parte aislada del documento, si se creara un elemento en en documento todas las nodeList deberán ser actualizadas.
Interfaz Node:
Esta es la interfaz principal y tiene los siguientes atributos de sólo lectura:
 |
nodeName |
 |
nodeValue |
 |
nodeType |
 |
parentNode |
 |
childNodes |
 |
firstChild |
 |
lastChild |
 |
previousSibling |
 |
nextSibling |
 |
attributes |
 |
ownerDocument |
El atributo nodeType:
Existen doce tipos de nodo identificados con un entero corto sin signo y también hay una constante mnemónica para cada uno.
 |
Elemento Es el más común y es el único que contiene elementos secundarios o hijos, los demás son hojas de un árbol. Los elementos también tienen atributos, que a la vez se consideran nodos pero no parte del árbol. |
 |
Attr Representa un atributo de un elemento y no se considera un secundario o hijo de un elemento. |
 |
Texto Siempre es una hoja del árbol DOM. |
 |
Sección CDATA Siempre es una hoja del árbol DOM. |
 |
Referencia de Entidad |
 |
Nodo de Entidad |
 |
Instrucción de Procesamiento |
 |
Comentario |
 |
Documento |
 |
Tipo de Documento |
 |
Fragmento de Documento |
 |
Notación |
| Tipo de elemento |
Entero |
Constante definida |
Elemento |
1 |
ELEMENT_NODE |
| Attr |
2 |
ATTRIBUTE_NODE |
| Texto |
3 |
TEXT_NODE |
| Sección CDATA |
4 |
CDATA_SECTION_NODE |
| Referencia de Entidad |
5 |
ENTITY_REFERENCE_NODE |
| Nodo de Entidad |
6 |
ENTITY_NODE |
| Instrucción de Procesamiento |
7 |
PROCESSING_INSTRUCTION_NODE |
| Comentario |
8 |
COMMENT_NODE |
| Documento |
9 |
DOCUMENT_NODE |
| Tipo de Documento |
10 |
DOCUMENT_TYPE_NODE |
| Fragmento de Documento |
11 |
DOCUMENT_FRAGMENT_NODE |
| Notación |
12 |
NOTATION_NODE |
Los atributos nodeName y nodeValue:
| Tipo de elemento |
nodeName |
nodeValue |
| Elemento |
tagName |
Null |
| Attr |
Nombre del atributo |
Valor del atributo |
| Texto |
#text |
Contenido del nodo |
| Sección CDATA> |
#cdata-section |
Contenido de la sección |
| Referencia de Entidad |
Nombre de la referencia de la entidad |
Null. El valor de sustitución de la referencia de la entidad se considera el primer nodo hijo. |
| Nodo de Entidad |
Nombre de la entidad |
El valor de sustitución de la referencia de la entidad se considera el primer nodo hijo. |
| Instrucción de Procesamiento |
Destino del PI |
Todo el contenido excluyendo el destino. |
| Comentario |
#comment |
Contenido del comentario |
| Documento |
#document |
El valor de sustitución de la referencia de la entidad se considera el primer nodo hijo. |
| Tipo de Documento |
Nombre del tipo de documento |
Null |
| Fragmento de Documento |
Fragmento del #document |
Null |
| Notación |
Nombre de la notación |
Null |
Otros atributos:
El atributo parentNode devuelve el nodo padre, childNodes devuelve una NodeList de todos los hijos de ese nodo, firstChild, lastChild, previousSibling y nextSibling se usan para recorrer el árbol DOM.
attributes funciona con los nodos de tipo de elemento, en los demás devuelve Null, sino devuelve un NamedNodeMap de todos los atributos, ownerDocument devuelve el objeto de documento como un nodo.
Interfaz Node:
El método insertBefore inserta un nodo hijo a partir del nodo padre que se referencie:
objeto_nodo.insertBefore(nuevo_nodo, nodo_referencia)
con replaceChild puede reemplazarse un nodo:
objeto_nodo.replaceChild(nodo_referencia)
para eliminar un nodo puede usarse removeChild:
objeto_nodo.removeChild(nodo_referencia)
appendChild adjunta un nuevo nodo al final de la lista de nodos hijos:
objeto_nodo.appendChild(nodo_referencia)
hasChildNodes() es un valor booleano que indica la presencia o no de nodos secundarios o hijos. Con cloneNode se puede clonar un determinado nodo, tiene un parámetro booleano en True clona el elemento con todo su contenido, en False clona el elemento:
documentElement.firstChild.cloneNode(True)
Hay que tener en cuenta que un nodo clonado es un nodo huérfano, para que dependa de algún nodo del árbol hay que efectuarlo explícitamente.
La interfaz NodeList:
Dándole un índice como parámetro de entrada al método item devuelve el nodo correspondiente a la posición del índice. Tener en cuenta que el índice es de base cero. El atributo lenght devuelve un entero que indica la cantidad de nodos que hay en la NodeList.
La interfaz NamedNodeMap:
Cuando se invoca el atributo attributes de la interfaz Node, este devuelve un NamedNodeMap, que tiene un índice aunque el orden de sus elementos no es relevante.
Para recuperar, añadir o eliminar nodos se usa getNamedItem(), setNamedItem() y removeNamedItem() respectivamente, setNamedItem() necesita un nodo como argumento, las dos restantes requieren una cadena.
El método item() devuelve el atributo que indica el índice. Con el atributo length tenemos la longitud de la interfaz NamedNodeMap.
La interfaz CharacterData:
Con esta interfaz se accede a las porciones de cadena de todos los métodos y atributos, pueden ser nodos de texto, de comentario o cualquiera otro que toman un valor como cadena.
El atributo data devuelve todo el texto del nodo como cadena de Unicode. Con el atributo length se conoce el número de caractéres de la cadena.
El método subStringData devuelve una subcadena, acepta dos argumentos, el primero define el despalzamiento y el segundo la longitud de la subcadena. El método appendData permite adjuntar al final de una cadena, otra cadena. Con insertData puede insertarse una cadena dentro de otra, tiene dos argumentos, el primero es la posición desde la cual insertar y el segundo es la cadena a insertar. Con deleteData se puede suprimir una subcadena, tiene dos argumentos, el primero de desplazamiento y el segundo de longitud. replaceData toma tres argumentos para reemplazar una subcadena, el primer argumento es el de desplazamiento, el segundo es la longitud y el tercero es la cadena de reemplazo.
La interfaz Attr:
Esta interfaz es un atributo de un elemento, no se lo considera parte del árbol, se lo toma como propiedad de un elemento.
El atributo name devuelve el nombre del atributo, value devuelve el valor. El atributo specified es de valor booleano, si se asigna valor al atributo, specified vale True, si por el contrario, tiene un valor predeterminado, vale False.
La interfaz Element:
En esta interfaz tenemos seis métodos para la manipulación de atributos, getAttribute devuelve el valor de un atributo por su nombre, tiene un parámetro de tipo string de entrada y otro del mismo tipo como salida, setAttribute sirve para crear un atributo y fijar su valor, recibe dos parámetros de entrada de tipo string, removeAttribute se usa para eliminar un atributo con un determinado nombre, acepta un parámetro de tipo string de entrada.
Los atributos pueden ser entidades, cuando tratemos este tipo de atributos, que llevan implícitos construcciones más o menos complejas, es más fácil manipularlos como nodos attr que como una cadena sencilla como el parámetro de salida de los tres métodos anteriores, entonces, nos vendría bárbaro tener duplicados estos métodos pero como parámetro de salida devuelvan un objeto de tipo nodo attr, para eso están los métodos getAttributeNode, setAttributeNode y removeAttributeNode.
Hasta aquí todo lo referente a la manipulación de atributos.
También tenemos el método getElementsByTagName tiene como parámetro de entrada un string y devuelve un NodeList de todos los elementos descendientes que tengan el nombre indicado en el nodo de elemento (existe un método homólogo en la interfaces Document y DocumentFragment pero en estos casos devuelve un documento completo o un fragmento respectivamente).
Otras interfaces:
La interfaz Text tiene un único método de nombre splitText, acepta un entero como parámetro de entrada y sirve para dividir en dos un nodo de tipo texto.
Si al comienzo de un documento se declara <!DOCTYPE la interfaz DocumentType develverá valores invocando los atributos name, entities y notations, en caso que no exista declaración <!DOCTYPE los atributos devuelven nulls, name devuelve el nombre de la DTD, entities devuelve un NamedNodeMap de todas las entidades, internas o externas declaradas en la DTD, notation también devuelve un NamedNodeMap de todas las notaciones que se declaran en la DTD.
Para ver la interfaz Notation, hay que entender que las declaraciones de notaciones se consideran propiedades de DocumentType, veamos un ejemplo en pseudocódigo con el que crear un NamedNodeMap:
ObjetoNamedNodeMap = objetoDocumentType.notations
La cantidad de notaciones se puede obtener con:
ObjetoNamedNodeMap.length
Si quisiéramos obtener la primera notación podemos usar el método item de la siguiente manera:
ObjetoNotation = ObjetoNamedNodeMap.item(0)
Este ObjetoNotation tiene todos los atributos comunes a cualquier nodo y además otros dos de nombre publicId que identifica cualquier identificador PUBLIC y systemId que identifica cualquier identificador SYSTEM.
Existe una interfaz llamada ProcessingInstruction con dos atributos de nombre target y data.
Lo escrito hasta aquí no agota las posibilidades de las interfaces descriptas, además existen otras interfaces del DOM. Pero con lo expuesto hasta aquí se puede explotar DOM para hacer muchas cosas.
Aplicación práctica sobre Visual Basic y ASP:
De ahora en más me voy a ocupar de la implementación Microsoft del DOM, esta es bastante exacta y las diferencias no van más allá de unas pocas diferencias en cuanto a camelbacks (un camelback es una palabra que mezcla mayúsculas y minúsculas entre sus caracteres, por ejemplo camelBack). Esta implementación descansa en una dll de nombre MSXML.dll y se lo pueden bajar desde http://msdn.microsoft.com donde además puede encontrar mucha información sobre esta tecnología.
La pregunta que surge inevitablemente es: ¿Cómo uso DOM en la vida real?
Bien, aquí hago otro corte, vamos a verlo desde Visual Basic.
En primer lugar hay que tener en cuenta que debe existir una referencia en el proyecto a la biblioteca correspondiente. Para eso en ambiente de desarrollo Visual Basic desplegamos el popup de la opción Project del menú principal y elegir References,

ojalá lleguen a verlo, pero esta es la lista de referencias que se abre, está resaltada la versión 2.6 de la implementación Microsoft del DOM, debajo podemos ver la versión 2.0 que es la que vamos a usar.
El tema se reduce ahora a declarar los objetos necesarios para poder manipular un archivo XML. Veamos como cargar un documento XML desde Visual Basic
Dim objXMLDOMDoc As MSXML.DOMDocument
Set objXMLDOMDoc = New MSXML.DOMDocument
objXMLDOMDoc.Load("Automoviles.xml")
Si hablamos de un script ASP necesitamos el siguiente código. Para crear un instancia ADO del lado del cliente usamos:
Dim objXMLDOMDoc
Set objXMLDOMDoc = createObject("MICROSOFT.XMLDOM")
Para crear una instancia similar del lado del servidor usaremos:
Dim objXMLDOMDoc
Set objXMLDOMDoc = server.createObject("MICROSOFT.XMLDOM")
Tanto desde el lado cliente como servidor para cargar un documento XML se usa:
objXMLDOMDoc.Load("Automoviles.xml")
Este es un ejemplo en el que se utiliza DOM en Visual Basic. A continuación vemos el código:
Option Explicit
Dim objXMLDoc As MSXML.DOMDocument
Dim objXMLDOMElement As MSXML.IXMLDOMElement
Dim strXML As String
Dim strDoc As String
Private Sub Form_Load()
'Instancio un objeto de tipo documento XML
Set objXMLDoc = New MSXML.DOMDocument
'Establezco el documento XML a tratar
strDoc = App.Path & "\Automoviles.xml"
'Inicializo la variable que soportará el parseo del documento XML
strXML = ""
'Abro el Documento
objXMLDoc.Load (strDoc)
'Le paso al procedimiento Parse un NodeList de todos los elementos básicos del documento XML
Parse objXMLDoc.childNodes
'Vuelco al textBox el contenido de la variable strXML que contiene el parseo del documento XML
txt.Text = strXML
Set objXMLDoc = Nothing
End Sub
Private Sub Parse(ByRef Nodes As MSXML.IXMLDOMNodeList)
Dim xNode As MSXML.IXMLDOMNode
'Recorro la colección de nodos de la NodeList que se recibe como argumento
For Each xNode In Nodes
'Cada nodo de tipo Element lo paso como parámetro del procedimiento ParseElement
If xNode.nodeType = NODE_ELEMENT Then
ParseElement xNode
End If
Next xNode
End Sub
Private Function ParseElement(mobjElemento As MSXML.IXMLDOMElement) As String
Dim intIndiceNodo As Integer
Dim intIndiceAtributo As Integer
Dim objXMLDOMNodeList As MSXML.IXMLDOMNodeList
'Verifico que el nodo tenga hijos
If mobjElemento.hasChildNodes Then
'Seteo un objeto de tipo NodeList con los hijos del nodo a tratar
Set objXMLDOMNodeList = mobjElemento.childNodes
'Recorro estos nodos hijos
For intIndiceNodo = 0 To objXMLDOMNodeList.length - 1
If Not objXMLDOMNodeList.Item(intIndiceNodo) Is Nothing Then
'Verifico que sea un nodo de tipo Element
If objXMLDOMNodeList.Item(intIndiceNodo).nodeType = NODE_ELEMENT Then
strXML = strXML & "<" & objXMLDOMNodeList.Item(intIndiceNodo).nodeName
If objXMLDOMNodeList.Item(intIndiceNodo).Attributes.length > 0 Then
For intIndiceAtributo = 0 To objXMLDOMNodeList.Item(intIndiceNodo).Attributes.length - 1
strXML = strXML & Space(1) &
objXMLDOMNodeList.Item(intIndiceNodo).Attributes.Item(intIndiceAtributo).nodeName & "=" & Chr(34) & objXMLDOMNodeList.Item(intIndiceNodo).Attributes.Item(intIndiceAtributo).nodeValue & Chr(34) '& Space(1)
Next intIndiceAtributo
End If
strXML = strXML & ">" & vbCrLf
ParseElement objXMLDOMNodeList.Item(intIndiceNodo)
strXML = strXML & "</" & objXMLDOMNodeList.Item(intIndiceNodo).nodeName & ">" & vbCrLf
'Verifico que sea un nodo de tipo Texto
ElseIf objXMLDOMNodeList.Item(intIndiceNodo).nodeType = NODE_TEXT Then
'Agrego el texto
strXML = strXML & objXMLDOMNodeList.Item(intIndiceNodo).nodeValue & vbCrLf
'Verifico que sea un nodo de tipo Instrucción de Procesamiento
ElseIf objXMLDOMNodeList.Item(intIndiceNodo).nodeType = NODE_PROCESSING_INSTRUCTION
Then
'Agrego el tag
strXML = strXML & "<?" & objXMLDOMNodeList.Item(intIndiceNodo).nodeName & Space(1) &
objXMLDOMNodeList.Item(intIndiceNodo).nodeValue & "?>"
'Verifico que sea un nodo de tipo Comentario
ElseIf objXMLDOMNodeList.Item(intIndiceNodo).nodeType = NODE_COMMENT Then
'Agrego el comentario
strXML = strXML & "<!-" & objXMLDOMNodeList.Item(intIndiceNodo).nodeValue & "->"
'Verifico que sea un nodo de tipo Tipo de Documento
ElseIf objXMLDOMNodeList.Item(intIndiceNodo).nodeType = NODE_DOCUMENT_TYPE Then
'Agrego el tag de tipo de documento
strXML = strXML & "<!DOCTYPE" & Space(1) &
objXMLDOMNodeList.Item(intIndiceNodo).nodeName & " SYSTEM 'Automoviles.dtd' >"
End If
End If
Next intIndiceNodo
End If
ParseElement = strXML
Set objXMLDOMNodeList = Nothing
End Function
Vemos como desde un procedimiento llamado ParseElement que recibe como argumento el método childNodes aplicado sobre el objeto documento XML, esto no es más que una NodeList de todos los elementos básicos del documento. En ParseElement se recorren todos los elementos del documento XML, para cada elemento de tipo Element se llama a la función ParseElement pasándole como argumento el nodo de tipo Element, esta función es recursiva y analiza el nodo en profundidad, lo desmenuza en atributos, argumentos, elementos y contenido de tipo carácter, lo rearma volcando el resultado en un cuadro de texto.
Ustedes se preguntarán cual es la aplicación práctica del ejemplo, pues claro que ninguna.
La idea es ver como manipular todos los elementos posibles desde el DOM que implementa Microsoft. Este ejemplo trata nodos de tipo Element, Text, ProcessingInstruction, Comment y DocumentType.
Otro ejemplo, esta vez en una página ASP, a continuación vemos el código:
<%@ Language=VBScript %>
<HTML>
<HEAD>
</HEAD>
<BODY>
<%
Dim objFileSystemObject
Dim objTextStream
Dim objConnection
Dim objCommand
Dim rs
Dim objXMLDOMDoc
Dim strConnectionString
Dim strLocation
Dim strSQL
Dim strXML
Dim intIndiceField
Dim strSource
Dim strRaiz
'Instancio un objeto de conexión
Set objConnection = CreateObject("ADODB.Connection")
'Instancio un objeto comando
Set objCommand = CreateObject("ADODB.Command")
'Instancio un objeto Recordset
Set rs = CreateObject("ADODB.Recordset")
'Instancio un objeto Documento DOM
Set objXMLDOMDoc = CreateObject("Microsoft.XMLDOM")
'Establezco el string de conexión
strLocation = server.MapPath("db.mdb")
strConnectionString = "Driver={Microsoft Access Driver (*.mdb)}; DBQ=" & strLocation & ";"
'Abro la conexión
objConnection.Open (strConnectionString)
'Activo el objeto comando
Set objCommand.ActiveConnection = objConnection
'Establezco el string de la consulta SQL
strSQL = "SELECT * FROM Contacto"
objCommand.CommandText = strSQL
'Efectúo la consulta SQL llenando el Recordset
rs.Open objCommand
strXML = ""
'Establezco el elemento raiz
strSource = Right(rs.Source, Len(rs.Source) - (InStr(1, rs.Source, "FROM ") + Len("FROM ") - 1))
strRaiz = strSource & "Raiz"
'Instancio un objeto FileSystemObject
Set objFileSystemObject = CreateObject("Scripting.FileSystemObject")
'Instancio un objeto TextStream donde voy a guardar el archivo XML resultante
Set objTextStream = objFileSystemObject.CreateTextFile(server.MapPath("PruebaXML.xml"))
'Abro el elemento raiz
strXML = strXML & "<" & strRaiz & ">" & vbCrLf
'Abro el elemento raiz en el TextStream
objTextStream.writeLine "<" & strRaiz & ">" & vbCrLf
'Recorro el Recordset
Do While Not rs.EOF
'Abro un elemento padre (registro)
strXML = strXML & "<" & strSource & ">" & vbCrLf
'Abro un elemento padre en el TextStream
objTextStream.writeLine "<" & strSource & ">" & vbCrLf
'Recorro la colección de Fields de la tabla
For intIndiceField = 0 To rs.Fields.Count - 1
'Abro, adjunto contenido y cierro un elemento hijo (campo)
strXML = strXML & "<" & rs.Fields(intIndiceField).Name & ">" & rs.Fields(intIndiceField).Value & "</" & rs.Fields(intIndiceField).Name & ">" & vbCrLf
'Abro, adjunto contenido y cierro un elemento hijo en el TextStream
objTextStream.writeLine "<" & rs.Fields(intIndiceField).Name & ">" & rs.Fields(intIndiceField).Value & "</" & rs.Fields(intIndiceField).Name & ">" & vbCrLf
Next
'Cierro un elemento padre (registro)
strXML = strXML & "</" & strSource & ">" & vbCrLf
'Cierro un elemento padre en el TextStream
objTextStream.writeLine "</" & strSource & ">" & vbCrLf
rs.MoveNext
Loop
'Cierro el elemento raiz
strXML = strXML & "</" & strRaiz & ">"
'Cierro el elemento raiz en el TextStream
objTextStream.writeLine "</" & strRaiz & ">"
'Muestro en el browser el contenido de la tabla a través de una cadena XML
Response.Write strXML
'Cierro el objeto TextStream
objTextStream.close
Set objTextStream = Nothing
Set objFileSystemObject = Nothing
Set objXMLDOMDoc = Nothing
Set rs = Nothing
Set objCommand = Nothing
Set objConnection = Nothing
%>
</BODY>
</HTML>
Aquí nos conectamos a una base de datos Access de nombre db.mdb, que contiene una tabla llamada Contacto, que contiene los campos Nombre, Apellido, TE e eMail, el nombre de los campos no es relevante, desde el punto de vista del script, ya que se utiliza la colección Fields. Esta página ASP tiene dos outputs uno a través de browser, donde se muestra el contenido de los registros de la tabla Contacto y el otro es un archivo XML de nombre PruebaXML.xml generado a través del objeto FileSystemObject. Este código puede ampliarse y optimizarse tanto como tiempo quieran dedicarle, la idea básica es usar páginas ASP, el objeto FileSystemObject, XML y ADO como mecanismo de acceso a una base de datos.
Se puede encontrar más información sobre XML y Visual Basic en http://www.vbxml.com/
Carlos Marcelo Santos.
