convertir c# xml c#-4.0 xmlreader

convertir xml a dataset c#



XmlReader-Necesito editar un elemento y producir uno nuevo (5)

Lo arreglé usando la siguiente codificación de cinta adhesiva

public XmlReader FixUpReader(XmlReader reader) { reader.MoveToContent(); string xml = reader.ReadOuterXml(); string dslVersion = GetDSLVersion(); string Id = GetID(); string processedValue = string.Format("<ExampleElement dslVersion=/"{1}/" Id=/"{2}/" ", dslVersion, Id); xml = xml.Replace("<ExampleElement ", processedValue); MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml)); XmlReaderSettings settings = new XmlReaderSettings(); XmlReader myReader = XmlReader.Create(ms); myReader.MoveToContent(); return myReader; }

Me siento sucio por hacerlo de esta manera, pero está funcionando ...

Estoy anulando un método que tiene un XmlReader que se transfiere, necesito encontrar un elemento específico, agregar un atributo y luego crear un nuevo XmlReader o simplemente reemplazar el existente con el contenido modificado. Estoy usando C # 4.0

He investigado el uso de XElement (Linq) pero parece que no puedo manipular un elemento existente y agregar un atributo y valor.

Sé que el XmlWriter tiene WriteAttributeString, que sería fantástico, pero una vez más, no estoy seguro de cómo encaja todo

Me gustaría poder hacer algo como --- ¡Esto es un pseudocódigo!

public XmlReader DoSomethingWonderful(XmlReader reader) { Element element = reader.GetElement("Test"); element.SetAttribute("TestAttribute","This is a test"); reader.UpdateElement(element); return reader; }


No se puede hacer esto fácilmente con XmlReader , al menos no sin leer todo el documento XML del lector, continuar con él y luego crear un nuevo XmlReader partir del resultado. XmlReader embargo, XmlReader no XmlReader uso de XmlReader , es decir, la posibilidad de transmitir documentos de gran tamaño.

Podrías derivar de XmlReader , reenviando la mayoría de las llamadas al lector existente, pero interceptándolas cuando sea necesario para agregar atributos adicionales, etc. ... pero sospecho que ese código sería realmente bastante complejo y frágil.


Prefiero cargar el xml en el objeto XmlDocument y usar la colección de Attributes para modificar el valor y llamar al método Save para actualizar este valor. El siguiente código funciona para mí.

public static void WriteElementValue ( string sName, string element, string value) { try { var node = String.Format("//elements/element[@name=''{0}'']", sName); var doc = new XmlDocument { PreserveWhitespace = true }; doc.Load(configurationFileName); var nodeObject = doc.SelectSingleNode(node); if (nodeObject == null) throw new XmlException(String.Format("{0} path does not found any matching node", node)); var elementObject = nodeObject[element]; if (elementObject != null) { elementObject.Attributes["value"].Value = value; } doc.Save(configurationFileName); } catch (Exception ex) { throw new ExitLevelException(ex, false); }

}

También he observado que cuando usas XmlWriter o XmlSerializer los espacios en blanco no se conservan correctamente, esto puede ser molesto a veces


string newvalue = "10"; string presentvalue = ""; string newstr = ""; XmlReader xmlr = XmlReader.Create(new StringReader(str)); while (xmlr.Read()) { if (xmlr.NodeType == XmlNodeType.Element) { if (xmlr.Name == "priority") { presentvalue = xmlr.ReadElementContentAsString(); newstr = str.Replace(presentvalue, newvalue); } } }

// newstr se puede volver a escribir en el archivo ... que es el xml editado


XmlReader / Writer son secuencias de acceso secuenciales. Tendrá que leer en un extremo, procesar la transmisión como lo desee y escribirla en el otro extremo. La ventaja es que no necesita leer todo en la memoria y crear un DOM, que es lo que obtendría con cualquier enfoque basado en XmlDocument.

Este método debería ayudarlo a comenzar:

private static void PostProcess(Stream inStream, Stream outStream) { var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " }; using (var reader = XmlReader.Create(inStream)) using (var writer = XmlWriter.Create(outStream, settings)) { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: writer.WriteStartElement(reader.Prefix, reader.Name, reader.NamespaceURI); writer.WriteAttributes(reader, true); // // check if this is the node you want, inject attributes here. // if (reader.IsEmptyElement) { writer.WriteEndElement(); } break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.EndElement: writer.WriteFullEndElement(); break; case XmlNodeType.XmlDeclaration: case XmlNodeType.ProcessingInstruction: writer.WriteProcessingInstruction(reader.Name, reader.Value); break; case XmlNodeType.SignificantWhitespace: writer.WriteWhitespace(reader.Value); break; } } } }

Esto no es tan limpio como obtener tu propio XmlWriter, pero creo que es mucho más fácil.

[EDITAR]

Un ejemplo de cómo abriría dos transmisiones a la vez podría ser algo como esto:

using (FileStream readStream = new FileStream(@"c:/myFile.xml", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write)) { using (FileStream writeStream = new FileStream(@"c:/myFile.xml", FileMode.OpenOrCreate, FileAccess.Write)) { PostProcess(readStream, writeStream); } }