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
.
精彩评论