Creando un visor de XML (Parte I)
Martes 12 de Septiembre de 2006 a las 23:58En este artículo se describe el proceso de desarrollo de una pequeña herramienta que permitirá formatear un documento XML haciendo que resulte más legible, mostrarlo mediante un árbol, y seleccionar nodos mediante XPath visualizando aquéllos que respondan a la expresión de búsqueda resaltados. Adicionalmente se le añadirán otras características secundarias como el guardar y cargar ficheros, una lista de archivos recientes, ajuste de línea y expansión y contracción de todos los nodos del árbol. Es una herramienta sencilla pero que puede ser bastante útil para trabajar con XML.
Debido a sus dimensiones, este artículo ha sido dividido en dos partes. Se puede consultar la segunda parte en la siguiente dirección.
El resultado final de la aplicación mostrando sus tres vistas será el siguiente:
FORMATEANDO EL DOCUMENTO XML:
El código para formatear el texto se basa en dos funciones. La primera de ellas se llama FormatearTexto y se encargará de inicializar las variables, cargar el texto introducido en el primer RichTextBox en una variable del tipo XmlDocument. Esta primera función llamará a la segunda (IndentarXML), la cual es una función recursiva que se llamará así misma por cada nodo que tenga el arbol XML.
-
Private Sub FormatearTexto(ByVal consultar As Boolean)
-
Dim arbol As New Xml.XmlDocument
-
Dim profundidad As Integer
-
Dim cad As String
-
-
'Utilizados solo para hacer la consulta
-
Dim nodosSeleccionados As Xml.XmlNodeList
-
Dim inicioNodosSeleccionados As ArrayList
-
Dim finalNodosSeleccionados As ArrayList
-
Dim i As Integer
-
-
Try
-
arbol.LoadXml(rtxtXML.Text)
-
-
profundidad = 0
-
cad = ""
-
rtxtTextoFormateado.Text = ""
-
-
If arbol.FirstChild.NodeType = Xml.XmlNodeType.XmlDeclaration Then
-
cad &= arbol.FirstChild.OuterXml & vbCr
-
End If
-
If consultar Then
-
nodosSeleccionados = arbol.SelectNodes(txtConsulta.Text)
-
inicioNodosSeleccionados = New ArrayList
-
finalNodosSeleccionados = New ArrayList
-
IndentarXML(arbol.DocumentElement, cad, 0, nodosSeleccionados, inicioNodosSeleccionados, finalNodosSeleccionados)
-
rtxtTextoFormateado.Text = cad
-
For i = 0 To inicioNodosSeleccionados.Count - 1
-
rtxtTextoFormateado.Select(CInt(inicioNodosSeleccionados(i)), CInt(finalNodosSeleccionados(i)) - CInt(inicioNodosSeleccionados(i)))
-
rtxtTextoFormateado.SelectionColor = Color.Blue
-
rtxtTextoFormateado.SelectionFont = fuenteNegritaRTXT
-
Next
-
Else
-
IndentarXML(arbol.DocumentElement, cad, profundidad)
-
rtxtTextoFormateado.Text = cad
-
End If
-
Catch ex As Exception
-
MsgBox("Se ha producido el siguiente error:" & vbCrLf & vbCrLf & " - " & ex.Message)
-
End Try
-
End Sub
-
-
Private Function IndentarXML(ByVal nodo As Xml.XmlNode, ByRef cad As String, ByVal profundidad As Integer, Optional ByVal nodosSeleccionados As Xml.XmlNodeList = Nothing, Optional ByVal inicioNodosSeleccionados As ArrayList = Nothing, Optional ByVal finalNodosSeleccionados As ArrayList = Nothing) As String
-
Dim hijo As Xml.XmlNode
-
Dim atr As Xml.XmlAttribute
-
-
If nodo.NodeType <> Xml.XmlNodeType.Text And nodo.NodeType <> Xml.XmlNodeType.Comment Then
-
'cad &= New String(Chr(9), profundidad)
-
cad &= New String(" "c, profundidad * 7)
-
-
If Not nodosSeleccionados Is Nothing AndAlso estaSeleccionado(nodo, nodosSeleccionados) Then
-
If cad = "" Then
-
inicioNodosSeleccionados.Add(0)
-
Else
-
inicioNodosSeleccionados.Add(cad.Length - 1)
-
End If
-
-
End If
-
-
cad &= "<" & nodo.Name
-
For Each atr In nodo.Attributes
-
cad &= " " & atr.Name & "=""" & atr.Value & """"
-
Next
-
cad &= ">"
-
-
If Not nodosSeleccionados Is Nothing AndAlso estaSeleccionado(nodo, nodosSeleccionados) Then
-
finalNodosSeleccionados.Add(cad.Length)
-
End If
-
-
cad &= textoDelNodo(nodo)
-
-
If tieneHijos(nodo) Then
-
cad &= vbCr
-
For Each hijo In nodo.ChildNodes
-
IndentarXML(hijo, cad, profundidad + 1, nodosSeleccionados, inicioNodosSeleccionados, finalNodosSeleccionados)
-
Next
-
'cad &= New String(Chr(9), profundidad)
-
cad &= New String(" "c, profundidad * 7)
-
End If
-
cad &= "</" & nodo.Name & ">" & vbCr
-
End If
-
End Function
La función "FormatearTexto" recibe un parámetro que indica si se está realizando una consulta o no. Si es así, se obtendrán todos los nodos seleccionados por la consulta y se crearán dos arrayList para almacenar las posiciones iniciales y finales de los nodos seleccionados, para poder posteriormente resaltarlos en el RichTextBox.
La función "IndentarXML" se encarga de transformar el nodo en cadena formateada y de llamarse a si misma recursivamente por cada hijo que tuviera el nodo. El parámetro profundidad se va incrementando en uno en cada nivel del árbol, y sirve para tabular correctamente el texto de cada nodo. Si se esta consultando y el nodo actual pertenece a los nodos seleccionados por la consulta XPath, entonces se marcará su posición inicial y final añadiéndolas a los arrayList.
Continuación
Creando un visor de XML (Parte II)
