.net 呈现空XML元素,如<;此/>;,不是<;这></这>;在XmlDocument上使用Save()时

.net 呈现空XML元素,如<;此/>;,不是<;这></这>;在XmlDocument上使用Save()时,.net,xml,.net,Xml,我有一个.NETC#解决方案,它构建复杂的XmlDocument,然后将其通过连接发送到外部API。由于API中令人讨厌的怪癖,我需要能够呈现空元素,如: <empty /> 然后使用以下命令将postData写入web请求: webRequest.GetRequestStream().Write(postData,0,postData.Length) 谢谢 您可能知道,XML标准规定和完全等效,因此XmlDocument对象没有做错任何事情 您可以通过过滤器(可能是正则表达式)运

我有一个.NETC#解决方案,它构建复杂的XmlDocument,然后将其通过连接发送到外部API。由于API中令人讨厌的怪癖,我需要能够呈现空元素,如:

<empty />
然后使用以下命令将
postData
写入web请求:

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


谢谢

您可能知道,XML标准规定
完全等效,因此
XmlDocument
对象没有做错任何事情


您可以通过过滤器(可能是正则表达式)运行生成的XML,将非最小化标记的实例更改为最小化标记形式。然后,将带有最小化标记的过滤后的XML发送到
webRequest

XmlDocument保留加载其XML时定义元素的方式-如果输入有空元素,它将输出它们,如果它们是元素/EndElement,它也将维护它们。您可以预处理XmlDocument节点,一个简单的递归函数(如下所示)可以用于预处理

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);
            }
        }
    }
}
公共类堆栈溢出\u 6529793
{
公共静态无效测试()
{
XmlDocument doc=新的XmlDocument();
字符串xml=”“;
doc.LoadXml(xml);
MemoryStream ms=新的MemoryStream();
文件保存(ms);
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray());
collapseemptylements(doc.DocumentElement);
ms=新内存流();
文件保存(ms);
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray());
}
静态void collapseemptylements(XmlElement节点)
{
如果(!node.IsEmpty&&node.ChildNodes.Count==0)
{
node.IsEmpty=true;
}
foreach(node.ChildNodes中的XmlNode子节点)
{
if(child.NodeType==XmlNodeType.Element)
{
collapseemptylements((xmlement)子元素);
}
}
}
}

很好的解决方案!顺便说一下,您可以使用
node.HasChildNodes
而不是
node.ChildNodes.Count==0
。谢谢,这很有效。在我的特定场景中,它并没有折叠某些元素,这些元素确实有一个子节点,而子节点只是一个空文本元素。我可以通过将测试更改为
if(!node.IsEmpty&&(node.ChildNodes.Count==0 | |(node.ChildNodes.Count==1&&node.ChildNodes[0]。NodeType==XmlNodeType.Text&&string.IsNullOrEmpty(node.ChildNodes[0].InnerText)))来调整代码。
您和我都知道,而为旧CRM系统构建API的轻量级公司却没有。
MemoryStream ms = new MemoryStream();
xmlDoc.Save(ms);
ms.Position = 0;
byte[] postData = new byte[ms.Length];
ms.Read(postData, 0, postData.Length);
ms.Close();
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);
            }
        }
    }
}