SoloCodigo

CLR: .Net / Mono / Boo / Otros CLR => C# => Mensaje iniciado por: kalixe985 en Domingo 16 de Diciembre de 2007, 02:53

Título: Generación De Código Xml Desde C#
Publicado por: kalixe985 en Domingo 16 de Diciembre de 2007, 02:53
Hola!!!
Resulta que estoy haciendo una aplicación en C# (Windows Forms) que tiene que generar varios archivos con código XML. Por ejemplo, uno de los archivos generados podría tener la misma estructura que el siguiente:

Código: Text
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Application xmlns="http://www.dvdforum.org/2005/HDDVDVideo/Manifest">
  3.     <Region x="0" y="0" width="1920" height="1080" />
  4.     <script src="file:///dvddisc/ADV_OBJ/main.js" />
  5.     <Markup src="file:///dvddisc/ADV_OBJ/main.xmu" />
  6.     <Resource src="file:///dvddisc/ADV_OBJ/main.js" />
  7.     <Resource src="file:///dvddisc/ADV_OBJ/main.xmu" />
  8.     <Resource src="file:///dvddisc/ADV_OBJ/chapter1____e.png" />
  9.     <Resource src="file:///dvddisc/ADV_OBJ/chapter1_f__e.png" />
  10.     <Resource src="file:///dvddisc/ADV_OBJ/chapter1of__e.png" />
  11.     <Resource src="file:///dvddisc/ADV_OBJ/chapter2____e.png" />
  12.     <Resource src="file:///dvddisc/ADV_OBJ/chapter2_f__e.png" />
  13.     <Resource src="file:///dvddisc/ADV_OBJ/chapter2of__e.png" />
  14.     <Resource src="file:///dvddisc/ADV_OBJ/chapter3____e.png" />
  15.     <Resource src="file:///dvddisc/ADV_OBJ/chapter3_f__e.png" />
  16.     <Resource src="file:///dvddisc/ADV_OBJ/chapter3of__e.png" />
  17. </Application>
  18.  
A medida que avanzo, poco a poco voy conociendo las clases XML de C# y familiarizándome con ellas.
Mi aplicación tiene que funcionar como proyectos, de tal forma que  el usuario pueda guardar el código que ha generado y la siguiente vez que abra la aplicación, se cargue el último código XML que el usuario creó, para poder seguir modificándolo, añadiéndole o quitándole elementos.
En lo que se refiere a generar la líneas de código XML en un fichero, lo sé hacer, con la clase XmlTextWriter. Lo que necesito es saber si hay alguna forma de ir generando el código, por ejemplo en un stream, y cuando el usuario Guarde los cambios, entonces ese código generado se escriba persistentemente en un archivo XML. Con esto lo que quiero conseguir es que sólo se escriba el código generado en el archivo XML cuando el usuario guarde, y no antes. Creo que esta forma es mejor, ya que si fuera leyendo  y escribiendo  el archivo XML, a medida que se fuera modificando,  sería menos eficiente (lecturas y escrituras continuas de un mismo fichero XML) y menos práctico. ¿Qué opináis? ¿Se podría hacer de otra manera? Acepto consejos. También he pensado utilizar archivos temporales XML. ¿Me lo recomendáis? ¿Cómo me aconsejaríais que hiciera lo que quiero conseguir?

Por otra parte, ¿Hay algún método y/o clase que permita buscar elementos en un archivo XML, modificarlos, borrarlos o crear nuevos, indistintamente de la línea en que se encuentren? Me explico, por ejemplo, en el ejemplo de código que he puesto, me interesaría poder borrar un elemento Resource, según su atributo src, por ejemplo, o modificar este elemento Resource o crear uno nuevo, etc...; me interesaría, por ejemplo, modificar, eliminar o volver a crear un elemento Region también...
Querría hacer lo anterior con todos los demás elementos (Region, Script, Markup, etc...): poderlos crear nuevos, borrarlos o modificarlos. ¿Cómo podría hacer esto?

Perdón por todas la dudas que planteo y por mi ignorancia. De antemano agradezco cualquier enlace a tutoriales, etc de XML con C#.

A ver si alguien me puede ayudar, gracias y salu2!!!!!
Título: Re: Generación De Código Xml Desde C#
Publicado por: JuanK en Domingo 16 de Diciembre de 2007, 16:20
Para escribir en  memoria:

MemoryStream

y luego hacerle un cast al XmlWriter/Reader

Para leer y escribir XML

XLMReader
XLMWriter
XLMTextReader
XLMTextWriter


usa los metodos find, nextSibling, nextRecord etc.

Tambien puedes usar

XMLDocument
Título: Re: Generación De Código Xml Desde C#
Publicado por: sergiotarrillo en Domingo 16 de Diciembre de 2007, 21:36
este cuadrito me gusta: At-A-Glance: XmlReader vs. XPathNavigator vs. XmlDocument (http://www.hanselman.com/blog/AtAGlanceXmlReaderVsXPathNavigatorVsXmlDocument.aspx)

Saludos,
Título: Re: Generación De Código Xml Desde C#
Publicado por: kalixe985 en Lunes 17 de Diciembre de 2007, 00:41
Creo que optaré por XmlDocument y XpathNavigator. Me pondré a estudiar estas clases y ya iré comentando si tengo problemas.
Gracias y salu2!!!!
Título: Re: Generación De Código Xml Desde C#
Publicado por: kalixe985 en Lunes 17 de Diciembre de 2007, 23:21
Hola de nuevo!!!
Resulta que el código XML que debo generar debe cumplir un schema existente. En este punto necesitaria dos cosas:A ver si me pueden ayudar.
Gracias y salu2!!!!
Título: Re: Generación De Código Xml Desde C#
Publicado por: kalixe985 en Sábado 29 de Diciembre de 2007, 03:35
HOla de nuevo!!!
Vuelvo a tener problemas con las clases de XML en C#.
Resulta que tengo un código XML como el siguiente:
Código: Text
  1. ?xml version="1.0" encoding="utf-8"?>
  2. <Application xmlns="http://www.google.com">
  3.   <Region x="0" y="0" width="1920" height="1080" />
  4.   <script src="archivo1" />
  5.   <Markup src="archivo2" />
  6.   <Resource src="archivo1" />
  7.   <Resource src="archivo2" />
  8. </Application>
  9.  

Por mi aplicación, necesito insertar y eliminar nodos del tipo <Resource>, es decir, de los 2 últimos. Para insertar (al final, por ejemplo), no tengo ningún problema ya que puedo clonar alguno de los <Resource>, modificarlo e insertarlo. Mi problema surge a la hora de eliminar un nodo <Resource> según su atributo src. Si utilizo la expresión
Código: Text
  1. XmlNode deleteContact = xmlDocument.SelectSingleNode(&#34;//Resource[@src='archivo1']&#34;);
  2. deleteContact.ParentNode.RemoveChild(deleteContact);
  3.  
Resulta que me sale una NullReferenceException. He descubierto que esto sucede porque el nodo raíz <Application> tiene un namespace xmlns="http://www.google.com". Si quito el namespace y pongo un atributo cualquiera o simplemente dejo el nodo <Application> sin atributos, el código anterior sí que borra correctamente el nodo (en este caso borraría   <Resource src="archivo1" /> ). Para que funcione debo modificar el código XML de esta forma (o dejar <Application> sin atributos):
Código: Text
  1. &#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&#62;
  2. &#60;Application atributo=&#34;http://www.google.com&#34;&#62;
  3.   &#60;Region x=&#34;0&#34; y=&#34;0&#34; width=&#34;1920&#34; height=&#34;1080&#34; /&#62;
  4.   &#60;script src=&#34;archivo1&#34; /&#62;
  5.   &#60;Markup src=&#34;archivo2&#34; /&#62;
  6.   &#60;Resource src=&#34;archivo1&#34; /&#62;
  7.   &#60;Resource src=&#34;archivo2&#34; /&#62;
  8. &#60;/Application&#62;
  9.  


¿Cómo puedo borrar nodos si el nodo raíz tiene un namespace? Por cierto y dicho sea de paso, el código XML del principio lo cargo desde una plantilla, con lo cual no he creado el namespace yo mediante código.


Otra cosa que me gustaría saber es si hay alguna forma de cambiarle el nombre a un nodo (pasar de un nodo <nombre1 ... ... /> a tener un nodo <nombre2 ... ... />), sin tener que crear un nodo nuevo, simplemente modificando un nodo ya existente.
Lo mismo me gustaría hacerlo con los nombres de atributos. En resumen, si tengo:
Código: Text
  1. &#60;Resource src=&#34;archivo1&#34; /&#62;
  2.  
 me gustaría obtener, modificando este nodo, el nodo
Código: Text
  1. &#60;Pepito atributo=&#34;valorCualquiera&#34; /&#62;
  2.  



A ver si me podéis echar una manito.
Gracias de antemano y salu2!!!!!
Título: Re: Generación De Código Xml Desde C#
Publicado por: kalixe985 en Domingo 6 de Enero de 2008, 02:14
Hola de nuevo!!!

Tengo un problema a la hora de eliminar un nodo xml. Resulta que el nodo tiene la siguiente estructura:

<cue use="ButtonHover" begin="class('chapterButton')[state:pointer()=true()]" dur="1f" />

y me gustaría poder eliminarlo según su atributo begin, ya que hay muchos nodos de este tipo y yo sólo quiero eliminar uno en concreto, cada vez que quiera. El problema está en que el contenido del atributo tiene comillas simples ( ' ), lo cual me interfiere a la hora de seleccionar el nodo con una expresión xpath, para luego poder eliminarlo.

He probado con:

Código: Text
  1.  
  2. XmlNode deleteContact = contacto.SelectSingleNode(&#34;//_namespace:cue[@begin='class('chapterButton')[state:pointer()=true()]&#34;, nsmanager);
  3.  
  4. deleteContact.ParentNode.RemoveChild(deleteContact);
  5.  


Pero no me funciona por culpa de las comillas ( ' ). ¿Cómo puedo escoger el nodo entonces, o hay alguna forma de escogerlo con xpath y que no falle por las comillas simples ( ' )?

 

Gracias de antemano y salu2!!!
Título: Re: Generación De Código Xml Desde C#
Publicado por: ing_marco en Miércoles 14 de Mayo de 2008, 22:30
Hola.
Particularmente, yo trabajo con XMLNode, partir de alli creoun xpathnavigator y trabajo con esto.

XmlNode deleteContact = xmlDocument.SelectSingleNode("//Resource[@src='archivo1']");

haber en ese codigo hay 2 cosas que deberias revisar:
1: SelectSingleNode devuelve un xpathnavigator y tu lo estas tratando de asignar a un xmlnode.
2:Te recomiento que pruebes poner la cadena completa.
"Application/Resource[@src='archivo1']"

por lo demas no creo que deberias tener ningun problema.
Si tienes algun problema me lo haces saber por este medio o sino a mi blog.
Título: Re: Generación De Código Xml Desde C#
Publicado por: kalixe985 en Miércoles 14 de Mayo de 2008, 23:02
Cita de: "ing_marco"
Hola.
Particularmente, yo trabajo con XMLNode, partir de alli creoun xpathnavigator y trabajo con esto.

XmlNode deleteContact = xmlDocument.SelectSingleNode("//Resource[@src='archivo1']");

haber en ese codigo hay 2 cosas que deberias revisar:
1: SelectSingleNode devuelve un xpathnavigator y tu lo estas tratando de asignar a un xmlnode.
2:Te recomiento que pruebes poner la cadena completa.
"Application/Resource[@src='archivo1']"

por lo demas no creo que deberias tener ningun problema.
Si tienes algun problema me lo haces saber por este medio o sino a mi blog.
Ya lo solucioné en su día. Gracias y salu2!!!     ;)