2008-10-12 25 views
40

Estoy creando un editor liviano en C# y me gustaría saber cuál es el mejor método para convertir una cadena en una cadena XML con un bonito formato. Espero que haya un método público en la biblioteca de C# como "bool público FormatAsXml (texto de cadena, cadena de salida formateadaXmlText)", pero no podría ser tan fácil, ¿o sí?En C#, ¿cuál es el mejor método para formatear una cadena como XML?

Muy específicamente, ¿cuál sería el método "SomeMethod" que produciría el resultado a continuación?

string unformattedXml; 
string formattedXml; 

unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>" 
formattedXml = SomeMethod(unformattedXml); 

Console.WriteLine(formattedXml); 

Salida:

<?xml version="1.0"?> 
    <book id="123"> 
    <author>Lewis, C.S.</author> 
    <title>The Four Loves</title> 
    </book> 

Respuesta

69
string unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>"; 
string formattedXml = XElement.Parse(unformattedXml).ToString(); 
Console.WriteLine(formattedXml); 

Salida:

<book> 
    <author>Lewis, C.S.</author> 
    <title>The Four Loves</title> 
</book> 

la declaración XML no se emite por ToString(), pero es por Guardar() ...

XElement.Parse(unformattedXml).Save(@"C:\doc.xml"); 
    Console.WriteLine(File.ReadAllText(@"C:\doc.xml")); 

Salida:

<?xml version="1.0" encoding="utf-8"?> 
<book> 
    <author>Lewis, C.S.</author> 
    <title>The Four Loves</title> 
</book> 
+0

Gracias, esto es lo que estaba buscando :) – thatuxguy

+0

Parece que el método Parse() no analiza una cadena sin la declaración XML. –

0

¿Está la cadena XML válido? ¿Quiere decir cómo puede convertir una cadena XML en un documento XML? Si es así, haga lo siguiente:

XmlDocument xml = new XmlDocument(); 

xml.LoadXml(YourString); 
+1

¿No vio las otras dos o tres respuestas que dicen exactamente lo mismo? – cjk

5

Parece que usted quiere cargar el XML en un XmlTextWriter objetos y establecer el formato y la sangría propiedades:

writer.Formatting = Formatting.Indented; 
writer.Indentation = 1; 
writer.IndentChar = '\t'; 
+0

He usado este enfoque en el pasado (relativamente fácil), pero con .NET 2.0 y posterior, Microsoft ahora recomienda usar la clase XmlTextWrtierSettings para que pueda aprovechar las nuevas características agregadas en 2.0 y 3.5. Ver el enlace en mi respuesta. – Ash

15

Desafortunadamente no, que no es tan fácil como una El método FormatXMLForOutput, esto es Microsoft estaba hablando aquí;)

De todos modos, a partir de .NET 2.0, el enfoque recomendado es usar el XMlWriterSettingsClass para configurar el formateo, en lugar de establecer las propiedades directamente en el objeto XmlTextWriter. See this MSDN page para más detalles. Dice:

"En el lanzamiento de .NET Framework versión 2.0, la práctica recomendada es crear instancias XmlWriter utilizando el método XmlWriter.Create y la clase XmlWriterSettings. Esto le permite aprovechar al máximo todas las nuevas características introducidas en . esta versión Para obtener más información, consulte Creación de XML escritores "

Aquí se muestra un ejemplo del enfoque recomendado:.

XmlWriterSettings settings = new XmlWriterSettings(); 
settings.Indent = true; 
settings.IndentChars = (" "); 
using (XmlWriter writer = XmlWriter.Create("books.xml", settings)) 
{ 
    // Write XML data. 
    writer.WriteStartElement("book"); 
    writer.WriteElementString("price", "19.95"); 
    writer.WriteEndElement(); 
    writer.Flush(); 
} 
13

Usando el nuevo espacio de nombres System.Xml.Linq (Asamblea System.Xml.Linq) puede usar lo siguiente:

string theString = "<nodeName>blah</nodeName>"; 
XDocument doc = XDocument.Parse(theString); 

También puede crear un fragmento con:

string theString = "<nodeName>blah</nodeName>"; 
XElement element = XElement.Parse(theString); 

Si la cadena no está aún XML, se puede hacer algo como esto:

string theString = "blah"; 
//creates <nodeName>blah</nodeName> 
XElement element = new XElement(XName.Get("nodeName"), theString); 

Algo a destacar en este último ejemplo es que XElement XML Codificará la cadena proporcionada.

Recomiendo encarecidamente las nuevas clases XLINQ. Son más livianos y más fáciles de usar que la mayoría de los tipos existentes relacionados con XmlDocument.

1

Si sólo tiene que escapar caracteres XML la siguiente podría ser útil:

string myText = "This & that > <> &lt;"; 
myText = System.Security.SecurityElement.Escape(myText); 
4

El enfoque de Jason es el más simple. Aquí está el método:

private static string FormatXmlString(string xmlString) 
{ 
    System.Xml.Linq.XElement element = System.Xml.Linq.XElement.Parse(xmlString); 
    return element.ToString(); 
} 
+2

Bien podría hacer esa 1 línea. – mpen

9

Suponiendo que tu estás simplemente querer volver a formatear un documento XML para poner nuevos nodos en nuevas líneas y añadir la sangría, y luego, si está utilizando .NET 3.5 o superior, entonces la mejor solución es analizar luego la salida con XDocument, algo así como:

string unformattedXml; 
string formattedXml; 

unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>"; 
formattedXml = System.Xml.Linq.XDocument.Parse(unformattedXml).ToString(); 

Console.WriteLine(formattedXml); 

Neat hu?

Esto debería volver a formatear los nodos XML.

Para hacer esto con versiones anteriores de la estructura requiere mucho más trabajo de campo ya que no hay funciones integradas para volver a calcular el espacio en blanco.

De hecho, para hacer que el uso de clases de pre-LINQ sería:

string unformattedXml; 
string formattedXml; 

unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>"; 
System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); 
doc.LoadXml(unformattedXml); 
System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
System.Xml.XmlWriter xw = System.Xml.XmlTextWriter.Create(sb, new System.Xml.XmlWriterSettings() { Indent = true }); 
doc.WriteTo(xw); 
xw.Flush(); 
formattedXml = sb.ToString(); 
Console.WriteLine(formattedXml); 
0

System.Xml.Linq.XElement.ToString() formatea automáticamente!

XElement formattedXML = new XElement.Parse(unformattedXmlString); 
Console.WriteLine(formattedXML.ToString()); 
1

En Framework 4.0 que es sencilla.

var unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>"; 
var xdoc = System.Xml.Linq.XDocument.Parse(unformattedXml); 
var formattedXml = (xdoc.Declaration != null ? xdoc.Declaration + "\r\n" : "") + xdoc.ToString(); 
Console.WriteLine(formattedXml); 

Esto se suma a la sangría requerida, y mantiene la declaración XML.

<?xml version="1.0"?> 
<book> 
    <author>Lewis, C.S.</author> 
    <title>The Four Loves</title> 
</book> 
Cuestiones relacionadas