26

By default,

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

produces <my-tag />

I looked around XmlWriterSettings class for possible options that would force the writer to produce <my-tag></my-tag> instead but didn't find anything.

Is there a simple way of forcing the XmlWriter to issuing empty elements with "open tag, close tag" rather than with the short-hand form?

Edit:
Yes! I realize that with regards to XML validity the two notations are equivalent, valid and all... I'm however working with legacy code which parses such XML using Read(), i.e. at node level (!) and fumbles things up by Read()-ing when on an empty node...

Hence my question comes in the context of limiting the amount of changes to this legacy code. The question is indeed overlapping with this SO question as suggested; none of the options offered there are however easily applicable to my situation.

Community
  • 1
  • 1
mjv
  • 73,152
  • 14
  • 113
  • 156
  • 1
    possible duplicate of [C#: XmlTextWriter.WriteElementString fails on empty strings?](http://stackoverflow.com/questions/1176202/c-xmltextwriter-writeelementstring-fails-on-empty-strings) – nemesv Jan 25 '12 at 21:31
  • You can find a solution here : http://stackoverflow.com/questions/13389960/how-to-use-xmlwritersettings-when-using-override-void-writeendelement It's works for me. – Portekoi Jun 07 '13 at 13:52

7 Answers7

20

This worked for me:

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

WriteEndElement still self closed the tag

mejobloggs
  • 7,937
  • 6
  • 32
  • 39
  • 2
    in my tests, if I do writer.WriteRaw(""), and then writer.WriteEndElement(), my tags were not self-closed. VS 2010. – CD Jorgensen Feb 27 '13 at 20:51
3

If you get the message Extension method can only be declared in non-generic, non-nested static class as the word this may be highlighted, simply create an extension class as shown below:

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

Hope this proves useful :-)

iggyweb
  • 2,373
  • 12
  • 47
  • 77
2

Try this:

x.WriteStartElement("my-tag"); 

//Value of your tag is null

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

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

x.WriteEndElement();
2

I use the next code:

if (string.IsNullOrEmpty(myStringValue))
{
   myWriter.WriteStartElement("mytag");
   myWriter.WriteFullEndElement();
}
else
{
   myWriter.WriteElementString("mytag", myStringValue);
}
Juan Carlos Velez
  • 2,840
  • 2
  • 34
  • 48
1

Leaving this here in case someone needs it; since none of the answers above solved it for me, or seemed like overkill.

    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();

The trick was to set the XmlWriterSettings.Indent = true and add it to the XmlWriter.

Edit:

Alternatively you can also use

w.Formatting = Formatting.Indented;

instead of adding an XmlWriterSettings.

PhoenixDev
  • 746
  • 2
  • 9
  • 22
1

Have you tried something like this:

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

Maybe make a utility class with that as a member function.

DwB
  • 37,124
  • 11
  • 56
  • 82
  • I haven't tried, but I suspect it would work. Alas I'm working with legacy code and I was going for the "least changes" approach... – mjv Jan 25 '12 at 21:37
  • a utility class or derive an XmlWriter class that does the above. Both will probably be a large number of edits, but either may also be the "least changes" approach. – DwB Jan 25 '12 at 21:42
  • Indeed this solution is also suggested at the "duplicate" question referenced above, along with the idea of making this an extension method. If all fails I may just do that, or rewrite the parser so that it work at _element_ level. Anyway, thanks for the suggestion – mjv Jan 25 '12 at 22:00
0

I just ran into this exact same issue, and while it seems like kind of a hack, this did indeed work and was very unintrusive to the existing code I had to work with.

private static XElement MakeElementLongHand(this XElement rootElem)
{
   rootElem.Value = " ";
   rootElem.Value = string.Empty;
   return rootElem;
}
Steve Danner
  • 21,818
  • 7
  • 41
  • 51