Como ya sabremos, almacenar datos en formato XML es una práctica bastante habitual por lo que para poder trabajar con esta clase de documentos LINQ ofrece una interfaz con la que se podrán realizar tanto consultas de acción como consultas de selección sobre cualquier fichero de tipo XML. Se trata de LINQ to XML.

En este artículo explicaré cómo usar esta herramienta y para ello realizaré un CRUD sobre un documento XML que guardaré en local en mi aplicación.

  • Antes de empezar:
    • Crear un proyecto en Visual Studio 2019 de tipo: Web Application ASP .NET Core.
    • Usaré Bootstrap para el diseño (opcional)
    • También añadir al proyecto el NuGet de Micorosoft.EntityFrameworkCore:
exploradorsoluciones

Y ahora, comencemos.

Primero, agregaré a mi aplicación el fichero XML. Esta clase de ficheros estáticos se deben de guardar en la carpeta wwwroot:

  • Agregar la carpeta wwwroot al proyecto (este paso no es necesario si se ha creado el proyecto con plantilla MVC) :
wwwrootagre
  • Dentro de esta carpeta agregamos otra que se llame Documents y en esta guardaremos nuestro documento XML:
xmlagregado

Para mi ejemplo, mi documento XML se llama: musica.xml. Esta es su estructura:

Captura de pantalla (636)

Para poder acceder a wwwroot y a sus carpetas vamos a crearnos una clase llamada PathProvider. Será un proveedor de rutas que facilitará las rutas de los ficheros que se encuentren dentro de wwwroot. Nos crearemos este fichero en una carpeta a la que llamaremos Helpers:

helpers

Una vez creada primeramente debemos de añadir una enumeración que se componga de los nombres de las carpetas de wwwroot con las que queramos trabajar:

EnumCarpetas

Por supuesto, la enumeración se encontrará fuera de la clase pero dentro del namespace de esta.

Como se puede observar, mi enumeración solo consta de un elemento que es la carpeta Documents en la que está almacenado mi fichero XML. Evidemente, si tuviera más carpetas a las que quisiera acceder también debería de añadirlas a mi enumeración.

Además, para trabajar con archivos locales es necesario hacer la inyección de la interfaz IWebHostEnvironment (importar de: Microsoft.AspNetCore.Hosting) la cual permitirá acceder a la carpeta wwwroot:

inyeccion dependencias

A continuación, vamos a crear un método que devuelva las rutas de los ficheros. Este método recibirá como parámetros el nombre del fichero y la carpeta desde donde se quiere recuperar el fichero en cuestión:

mappath

Analicemos el código. Primeramente, tenemos un String carpeta que será la carpeta a la cual se quiere acceder.

Usando un bucle if apuntando a las carpetas que tenemos en wwwroot y se le asigna a carpeta el nombre de la carpeta a la que se quiere acceder.

Usando el método .Combine (importar de: System.IO) se crea una ruta con el entorno, la carpeta seleccionada y su nombre de fichero indicado. Es importante usar el método .Combine ya que estamos en multiplataforma y este método se adaptará a las distintas maneras que puede haber de escribir una ruta en distintos sistemas operativos.

Por último, se devuelve la ruta completa.

Tener la clase PathProvider es una herramienta de lo más útil ya que es una clase que se crea una vez solo y que se puede usar en múltiples sitios de la aplicación.

A continuación vamos a crearnos dentro de la carpeta Models una clase Album para poder mapear el documento XML.

ClaseAlbum

Teniendo esto vamos a comenzar con los métodos CRUD.

Como buena praxis, crearé una interfaz en donde iré escribiendo los métodos que vaya haciendo. La interfaz se encontrará dentro de una carpeta llamada. Repositories:

carpetarepositories

Teniendo esto, primero haré los métodos para hacer las consultas de selección. Uno que recuperará todos los elementos del documento y otro que recuperará sólo uno de los elementos.

IRepopt1

Nota: recordar hacer la interfaz pública ya que por defecto es privada.

Y ahora, nos creamos el repositorio en sí con la interfaz implementada:

repoconinter

Por el momento dejamos los métodos como están ya que aún necesitamos algunos elementos para poder continuar.

Necesitaremos:

  • Hacer uso del objeto XDocument que representará el documento XML.
  • Inyectar el PathProvider para obtener la ruta de los ficheros.
  • Un String privado en el cual estará la ruta completa al documento.
repositorymusicactor

En el constructor de la clase hacemos la inyección del PathProvider y usando su método MapPath() recuperamos la ruta al documento:

repositorymusicactor

El método de la clase XDocument: .Load() apuntará a un documento XML a partir de la ruta que se le haya especificado como parámetro. En este caso, la ruta viene en la variable path.

  • Método GetAlbumes()

Para poder leer un documento XML hay que acceder a sus etiquetas y para ello se usa el método .Descendants(). A este método se le indica el nombre de la etiqueta de la que queramos recuperar sus etiquetas hijas.

En este caso quiero recuperar todas las etiquetas que desciendan de la etiqueta <ALBUM>

descendants

Teniendo esto vamos a indicar que por cada etiqueta XML que haya en el documento cree un objeto de la clase Album y los devuelva convertido en lista.

Para hacer esto usaremos los métodos Element() o Attribute() según corresponda.

Cuando hablamos de elementos en XML nos referimos a las etiquetas en sí. Por ejemplo en mi documento tengo las siguientes etiquetas:

Captura de pantalla (636)

<TITULO>, <AUTOR> y <FEHCAPUBLICACION> son etiquetas que se encuentran dentro de otra llamada <ALBUM> y para recuperarlas se usará el método Element()

En cambio, dentro de la etiqueta <ALBUM> tenemos un atributo: ID y para recuperarlo se usará el método Attribute().

Veámoslo con el código:

Captura de pantalla (641)_LI

Importante: a la hora de escribir los nombres de la etiquetas deben de estar igual que en el documento XML ya que LINQ to XML es case sensitive.

  • Método GetAlbum()

Este método será parecido al anterior. Recibirá el ID del elemento que se quiera recuperar del documento y devolverá el objeto que coincida con él:

Captura de pantalla (640)

Una vez tengamos estos dos métodos vamos a abrir el fichero Startup y en su método ConfigureServices() resolvemos las dependencias:

Captura de pantalla (637)

Y en su método Configure() le indicamos que vamos a hacer uso de ficheros estáticos para tener acceso a la carpeta wwwroot:

Captura de pantalla (638)_LI

Y por último para poder visualizarlo me voy a crear un controlador en la carpeta Controllers en el cual haré la inyección de la interfaz y llamaré a los métodos del repositorio. También, me crearé las vistas correspondientes usando Scaffolding.

Captura de pantalla (639)

No olvidar en el ActionLink de Details agregarle el parámetro del ID para que lo pueda enviar al método:

detailsbtn

Y este sería el resultado:

Captura de pantalla (653) vistadetails

Ahora, vamos a seguir con las consultas de acción.

  • Método para insertar un elemento XML.

Declaramos este método en la interfaz:

Captura de pantalla (646)

Será un método que no devolverá nada pero recibirá los elementos que luego insertaremos dentro del documento XML. En el repositorio implementamos este método.

Para poder insertar habrá que hacer uso de un objeto de la clase XElement. Este objeto representará un elemento del documento XML.

insertar1

En este caso, xelem representará a la etiqueta <ALBUM>. A este elemento será al que le iremos añadiendo los valores de los elementos y atributos que desciendan de él.

Para añadir el valor de un atributo se tienen dos formas. Una de ellas sería usando XAttribute. Por ejemplo creando un nuevo objeto XAttribute que contenga el nombre del atributo a crear y su valor asignado:

xelem.Add(new XAttribute("ID", id));

O se puede hacer usando el método .SetAttributeValue() y pasarle el nombre del atributo y su valor:

insertarattr

Para añadir nuevos elementos también se debe de usar XElement. La diferencia está en que además de pasarle el nombre de la etiqueta a crear habrá que pasarle el valor que tiene:

Captura de pantalla (647)

Y con el método .Add() se añaden los elementos a su etiqueta padre <ALBUM>

Y por último, el elemento xelem deberá ser añadido también a la etiqueta raíz del documento: <ALBUMES>

Captura de pantalla (647)

El método .Save() recibe la ruta en donde se encuentre nuestro documento y guarda los cambios hechos en él.

Para probarlo simplemente llamamos a este método en el controlador en un método al que llamaré Create así como su correspondiente vista:

  • HomeController:
homecreate
  • Vista Create:

Nota: importante que los name de los input coincidan con los parámetros del método HttpPost de Create.

vistaaddhtml

Y este sería el resultado:

vista add Captura de pantalla (648)

Vemos que también se ha añadido en el documento XML:

xmladd

Por último voy a explicar cómo hacer los métodos de modificar y eliminar. Ambos métodos tienen en común que van a atacar a un elemento XML ya existente y por ello, antes de empezar voy a crear un método privado que localizará este elemento a partir de su ID.

metodogetxelemet

Es un método que devuelve un objeto XElement en concreto para luego poder trabajar con él.

  • Método para eliminar un elemento.

Este método sí lo implementaré en la interfaz:

Captura de pantalla (646)

Recibirá el ID del elemento a eliminar.

El primer paso será, usando este ID localizar el elemento en cuestión y para ello usaremos el método GetXElement() creado anteriormente:

eliminarpt1

Una vez esté localizado, usando el método Remove() que provee la clase XElement lo borramos y guardamos cambios:

eliminarpt2

Y ahora toca hacer el método en el controlador que llame a este método:

deletehome

Y en la vista Index, añadimos al enlace Delete el parámetro que luego enviará y que será el ID del elemento a borrar:

btndelete

Al ejecutar y pulsar en el botón veremos que el elemento se borra del documento.

  • Método para modificar.

A diferencia del método de eliminar, no sólo recibirá como parámetro el ID si no que recibirá todas las propiedades para modificar.

Entonces, primero este método irá dentro de la interfaz y luego se implementará en el repositorio:

Captura de pantalla (646)

Como hemos hecho en el anterior método, usando el método GetXElement() localizamos el elemento a editar:

updatealbumpt1

Teniendo el elemento localizado modificamos sus propiedades asignándoles el valor que les llega por parámetros y guardamos los cambios en el documento adecuado con Save()

modificarpt2

Finalmente, solo quedaría crearse el método Edit en el controlador y su correspondiente vista.

En el método GET de Edit usando el método GetAlbum() enviaremos el objeto seleccionado al modelo para poder visualizarlo:

editget

Vista:

Captura de pantalla (654)

En la vista Index pasarle el ID al Action Link para enviarlo al método Edit:

Captura de pantalla (656)

Este es el resultado:

Voy a editar el registro de «One Direction«:

Captura de pantalla (655) Captura de pantalla (651)

Y esto sería todo. Siguiendo estos pasos podremos leer cualquier documento XML así como modificarlo, eliminarlo o insertar nuevos elementos.

Autora: Aurora Moreno López

Curso: Desarrollo Web Full Stack, MultiCloud y Multiplataforma

Centro: Tajamar

Año académico: 2020-2021

Enlace a GitHub: https://github.com/auroraMoreno/LeerDocXML.git

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.