C#: XmlTextWriter.WriteElementString fails on empt

2019-01-15 08:51发布

I'm using XmlTextWriter and its WriteElementString method, for example:

XmlTextWriter writer = new XmlTextWriter("filename.xml", null);

writer.WriteStartElement("User");
writer.WriteElementString("Username", inputUserName);
writer.WriteElementString("Email", inputEmail);
writer.WriteEndElement();

writer.Close();

The expected XML output is:

<User>
    <Username>value</Username>
    <Email>value</Email>
</User>

However, if for example inputEmail is empty, the result XML I get as as follows:

<User>
    <Username>value</Username>
    <Email/>
</User>

Whereas I would expect it to be:

<User>
    <Username>value</Username>
    <Email></Email>
</User>

What am I doing wrong? Is there a way to achieve my expected result in a simple way using XmlTextWriter?

4条回答
再贱就再见
2楼-- · 2019-01-15 09:19

Your output is correct. An element with no content should be written as <tag/>.

You can force the use of the full tag by calling WriteFullEndElement()

writer.WriteStartElement("Email");
writer.WriteString(inputEmail);
writer.WriteFullEndElement();

That will output <Email></Email> when inputEmail is empty.

If you want to do that more than once, you could create an extension method:

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

Then your code would become:

writer.WriteStartElement("User");
writer.WriteFullElementString("Username", inputUserName);
writer.WriteFullElementString("Email", inputEmail);
writer.WriteEndElement();
查看更多
够拽才男人
3楼-- · 2019-01-15 09:25

It doesn't fail <Tag/> is just a shortcut for <Tag></Tag>

查看更多
Explosion°爆炸
4楼-- · 2019-01-15 09:26

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.

查看更多
乱世女痞
5楼-- · 2019-01-15 09:35

Your code should be:

using (XmlWriter writer = XmlWriter.Create("filename.xml"))
{
    writer.WriteStartElement("User");
    writer.WriteElementString("Username", inputUserName);
    writer.WriteElementString("Email", inputEmail);
    writer.WriteEndElement();
}

This avoids resource leaks in case of exceptions, and uses the proper way to create an XmlReader (since .NET 2.0).

查看更多
登录 后发表回答