开发者

Render empty XML elements like <this />, not <this></this> when using Save() on XmlDocument

I have a .NET C# solution that builds complex XmlDocument then shoots it over the wire to an external API. Due to annoying quirks in the API I need to be able to render empty elements like:

<empty />

Not like this (which appears to开发者_运维知识库 happen by default):

<empty></empty>

In this scenario we're using a .NET XmlDocument object and to prepare it send as part of the HttpWebRequest I'm writing the XML document into a byte array with code like:

MemoryStream ms = new MemoryStream();
xmlDoc.Save(ms);
ms.Position = 0;
byte[] postData = new byte[ms.Length];
ms.Read(postData, 0, postData.Length);
ms.Close();

The postData is then written into the web request using:

webRequest.GetRequestStream().Write(postData, 0, postData.Length);

Thanks!


The XmlDocument preserves the way the elements were defined when it loads its XML - if the input had empty elements, it will output them as such, if they were Element/EndElement, it will maintain those as well. You can preprocess the XmlDocument node, a simple recursive function (like the one below) can be used for that.

public class StackOverflow_6529793
{
    public static void Test()
    {
        XmlDocument doc = new XmlDocument();
        string xml = "<root><item1></item1><item2></item2><item3/><item4 a='b'></item4><a:item5 xmlns:a='ns'></a:item5></root>";
        doc.LoadXml(xml);
        MemoryStream ms = new MemoryStream();
        doc.Save(ms);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

        CollapseEmptyElements(doc.DocumentElement);
        ms = new MemoryStream();
        doc.Save(ms);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }
    static void CollapseEmptyElements(XmlElement node)
    {
        if (!node.IsEmpty && node.ChildNodes.Count == 0)
        {
            node.IsEmpty = true;
        }

        foreach (XmlNode child in node.ChildNodes)
        {
            if (child.NodeType == XmlNodeType.Element)
            {
                CollapseEmptyElements((XmlElement)child);
            }
        }
    }
}


As you probably know, the XML standard says that <empty /> and <empty></empty> are exactly equivalent, so the XmlDocument object is not doing anything wrong.

What you might do is run the generated XML through a filter (which could probably be a regex) to change instances of the non-minimised tag into the minimised tag form. Then, send the filtered XML with the minimised tags to the webRequest.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜