2012-01-25 20 views
17

Por defecto,¿Podemos forzar que XmlWriter emita <my-tag></my-tag> en lugar de <my-tag/>?

someXmlWriter.WriteElementString("my-tag", someString); 

produce <my-tag />

Miré alrededor XmlWriterSettings clase para posibles opciones que obligarían al escritor para producir <my-tag></my-tag> lugar, pero no encontró nada.

¿Existe una manera simple de forzar al XmlWriter a emitir elementos vacíos con "etiqueta abierta, etiqueta de cierre" en lugar de con la forma abreviada?

Editar:
Sí! Me doy cuenta de que con respecto a la validez de XML las dos notaciones son equivalentes, válidas y todas ... Sin embargo, estoy trabajando con código heredado que analiza dicho XML usando Read(), es decir, a nivel de nodo (!) Y lee cosas por Read() -ing cuando en un nodo vacío ...

Por lo tanto, mi pregunta viene en el contexto de limitar la cantidad de cambios en este código heredado. La pregunta de hecho se superpone con this SO question según lo sugerido; ninguna de las opciones ofrecidas allí es, sin embargo, fácilmente aplicable a mi situación.

+0

¿Por qué? Ellos son equivalentes. – Quentin

+1

posible duplicado de [C#: XmlTextWriter.WriteElementString falla en cadenas vacías?] (Http://stackoverflow.com/questions/1176202/c-xmltextwriter-writeelementstring-fails-on-empty-strings) – nemesv

+0

Aquí puede encontrar una solución : http://stackoverflow.com/questions/13389960/how-to-use-xmlwritersettings-when-using-override-void-writeendelement obras de él para mí. – Portekoi

Respuesta

-11

No hay opción de configuración para hacer eso en .Net. Son lo mismo y cualquier analizador debería ser capaz de manejar XML válido.

+0

't siempre es más fácil probar que algo existe en lugar de algo no ;-). ¿Estás "bastante seguro" de que no hay enfoques de opción para forzar al XmlWriter a producir una u otra forma del elemento vacío? (es decir, de forma global en oposición al truco con WriteStart/WriteEndElement). ¿Sabes de MS u otras fuentes autorizadas que confirmarían esto? – mjv

+1

@mjv Sí. http://msdn.microsoft.com/en-us/library/system.xml.xmlwritersettings.xmlwritersettings.aspx Investigué exhaustivamente la semana pasada porque algunos middleware con los que lidiamos se estaban ahogando con una etiqueta de cierre automático durante una traducción. La única solución es una solución para escribir su propio método para hacerlo como se ha señalado. http://blogs.msdn.com/b/ericwhite/archive/2009/07/08/empty-elements-and-self-closing-tags.aspx –

+0

-1 porque NO son lo mismo en xhtml (que es xml). Las etiquetas de script, en particular, no son válidas si se cierran automáticamente, por lo que a veces es necesario evitar las etiquetas de cierre automático, incluso si no hay texto interno. –

1

Ha intentado algo como esto:

if (someString.Length > 0) 
{ 
    someXmlWriter.WriteElementString("my-tag", someString); 
} 
else 
{ 
    someXmlWriter.WriteStartElement("my-tag"); 
    someXmlWriter.WriteEndElement("my-tag"); 
} 

tal vez hacer una clase de utilidad con eso como una función miembro.

+0

No lo he intentado, pero sospecho que funcionaría. Desgraciadamente, estoy trabajando con el código heredado y estaba buscando el enfoque de "cambios mínimos" ... – mjv

+0

una clase de utilidad o derivar una clase XmlWriter que hace lo anterior. Ambos probablemente serán una gran cantidad de ediciones, pero también puede ser el enfoque de "cambios mínimos". – DwB

+0

De hecho, esta solución también se sugiere en la pregunta "duplicada" mencionada anteriormente, junto con la idea de hacer de esto un método de extensión. Si todo falla, puedo simplemente hacer eso, o volver a escribir el analizador para que funcione en _element_ level. De todos modos, gracias por la sugerencia – mjv

17

Esto funcionó para mí:

writer.WriteStartElement("my-tag"); 
writer.WriteRaw(someString); 
writer.WriteFullEndElement(); 

WriteEndElement siendo uno mismo cerró la etiqueta

+1

en mis pruebas, si escribo writer.WriteRaw (""), y luego writer.WriteEndElement(), mis etiquetas no se cerraron automáticamente. VS 2010. –

0

Me acabo de encontrar con este mismo problema exacto, y si bien parece una especie de truco, esto, efectivamente, trabajar y era muy discreto con el código existente con el que tenía que trabajar.

private static XElement MakeElementLongHand(this XElement rootElem) 
{ 
    rootElem.Value = " "; 
    rootElem.Value = string.Empty; 
    return rootElem; 
} 
3

Si recibe el mensaje Extension method can only be declared in non-generic, non-nested static class como la palabra this puede resaltarse, basta con crear una clase de extensión como se muestra a continuación:

public static class Extension 
{ 
    public static void WriteFullElementString(this XmlTextWriter writer, string localName, string value) 
    { 
     writer.WriteStartElement(localName); 
     writer.WriteRaw(value); 
     writer.WriteFullEndElement(); 
    } 
} 

Hope esto resulta útil :-)

1

Dejando esto aquí en caso de que alguien lo necesite; ya que ninguna de las respuestas anteriores me lo resolvió, o me pareció excesivo.

FileStream fs = new FileStream("file.xml", FileMode.Create); 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true; 
    XmlWriter w = XmlWriter.Create(fs, settings); 
    w.WriteStartDocument(); 
    w.WriteStartElement("tag1"); 

     w.WriteStartElement("tag2"); 
     w.WriteAttributeString("attr1", "val1"); 
     w.WriteAttributeString("attr2", "val2"); 
     w.WriteFullEndElement(); 

    w.WriteEndElement(); 
    w.WriteEndDocument(); 
    w.Flush(); 
    fs.Close(); 

El truco consistía en establecer el XmlWriterSettings.Indent = true y añadirlo a la XmlWriter.

Editar:

alternativa, se puede utilizar también

w.Formatting = Formatting.Indented; 

en lugar de añadir un XmlWriterSettings.

2

Prueba esto:

x.WriteStartElement("my-tag"); 

//Value of your tag is null 

If (<"my-tag"> == "") 

{ 
    x.WriteWhitespace(""); 
}else 
    x.WriteString(my-tag); 

x.WriteEndElement(); 
0

uso el siguiente código:

if (string.IsNullOrEmpty(myStringValue)) 
{ 
    myWriter.WriteStartElement("mytag"); 
    myWriter.WriteFullEndElement(); 
} 
else 
{ 
    myWriter.WriteElementString("mytag", myStringValue); 
}