Otra de las herramientas de un desarrollador que se vuelven completamente imprescindibles una ves que las conoces es XPath.
XPath es un estándar del W3C para realizar querys a documentos Xml, haciendo fácil filtrar los nodos de un documento de acuerdo a la estructura y atributos de los nodos.
Si no usamos XPath, tendríamos que iterar a través de todos los nodos de un documento Xml para obtener la información que buscamos.
Para no hacérsela mas larga voy a dejar que el código hable por si mismo.
Imaginen que tienen el siguiente Xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8" ?> <Sucursales> <Sucursal name="Matriz"> <Articulo name="Monitor" precio="1500"/> <Articulo name="Impresora" precio="400"/> </Sucursal> <Sucursal name="Mayoreo"> <Articulo name="Monitor" precio="1600"/> <Articulo name="Impresora" precio="500"/> </Sucursal> <Sucursal name="Menudeo"> <Articulo name="Monitor" precio="1800"/> <Articulo name="Impresora" precio="700"/> </Sucursal> </Sucursales> |
Y ustedes quieren saber tres cosas:
- ¿Que artículos con que precios se encuentran en la sucursal Matriz?
- ¿Que sucursales tienen monitores?
- ¿Que precio tiene una impresora en la sucursal menudeo?
Sin XPath estas tres simples preguntas se convierte en esta monstruosidad:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | using System; using System.Xml; using System.Collections.Generic; class Program { public static void Main() { XmlDocument document = new XmlDocument(); document.Load("Test.xml"); XmlNode sucursales = document.ChildNodes[1]; //Obtener los articulos de la sucursal matriz XmlNodeList articulosMatriz; foreach (XmlNode sucursal in sucursales.ChildNodes) if (sucursal.Name == "Sucursal") if (sucursal.Attributes["name"].Value == "Menudeo") articulosMatriz = sucursal.ChildNodes; //Obtener todas las sucursales que tienen monitores List<XmlNode> sucursalesConMonitor = new List<XmlNode>(); foreach (XmlNode sucursal in sucursales.ChildNodes) { if (sucursal.Name == "Sucursal") { foreach (XmlNode articulo in sucursal.ChildNodes) { if (articulo.Name == "Articulo") { if (articulo.Attributes["name"].Value == "Monitor") { sucursalesConMonitor.Add(sucursal); break; //Siguiente sucursal } } } } } //Obtener el precio de una impresora en la sucursal menudeo XmlNode impresoraSucursalMenudeo = null; foreach (XmlNode sucursal in sucursales.ChildNodes) { if (sucursal.Name == "Sucursal") { if (sucursal.Attributes["name"].Value == "Menudeo") { foreach (XmlNode articulo in sucursal.ChildNodes) { if (articulo.Name == "Articulo") { if (articulo.Attributes["name"].Value == "Impresora") { impresoraSucursalMenudeo = articulo; break; } } } if (impresoraSucursalMenudeo != null) break; //Se encontro el articulo, terminamos! } } } } } |
¡HORRIBLE!
Claro que si hicieron la tarea y saben XPath, ¡las cosas cambian dramáticamente!:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System; using System.Xml; class Program { public static void Main() { string xPathQuery; XmlDocument document = new XmlDocument(); document.Load("Test.xml"); //Obtener los articulos de la sucursal matriz xPathQuery = @"/Sucursales/Sucursal[@name='Matriz']/Articulo"; XmlNodeList nodes = document.SelectNodes(xPathQuery); //Obtener todas las sucursales que tienen monitores xPathQuery = @"/Sucursales/Sucursal[./Articulo[@name='Monitor']]"; nodes = document.SelectNodes(xPathQuery); //Obtener el precio de una impresora en la sucursal menudeo xPathQuery = @"/Sucursales/Sucursal[@name='Menudeo']/Articulo[@name='Impresora']"; XmlNode node = document.SelectSingleNode(xPathQuery); } } |
SIMPLE, SENCILLO Y HERMOSO
Si no saben nada al respecto lean por lo menos este tutorial de w3schools, no se arrepentirán.
P.S XPath es un estándar, por lo que no depende de .NET, puedes usarlo en Java, Python o lo que te de tu gana