C# 如何使用LINQXML强制显式标记关闭?

C# 如何使用LINQXML强制显式标记关闭?,c#,xml,linq,tags,C#,Xml,Linq,Tags,这与以下问题相同: 但我使用的是NET4.0,答案不再有效 问题是我保存的标记实际上没有值,我的输出XML如下所示: 但我需要的总是开始和结束标记,即 问题:怎么做 编辑 1. 添加空节点: if (field_xml == null) // always true, because I create the file for the first time { field_xml = new XElement(XMLKeys.field,String.Empty); tab

这与以下问题相同:

但我使用的是NET4.0,答案不再有效

问题是我保存的标记实际上没有值,我的输出XML如下所示:

但我需要的总是开始和结束标记,即

问题:怎么做

编辑 1. 添加空节点:

if (field_xml == null) // always true, because I create the file for the first time
{
    field_xml = new XElement(XMLKeys.field,String.Empty);
    table_xml.Add(field_xml);
}
field_xml.SetAttributeValue(XMLKeys.name, field_info.Name);
// ... setting some other attributes of this node
稍后,保存xml:

var writer = new FullEndingXmlTextWriter(parameters.OutputFilename, Encoding.UTF8);
root_xml.Save(writer);

FullEndingXmlTextWriter是邪恶的Greebo指出的特殊类(它应该强制显式结束标记)。

XElement
的值设置为
String.Empty

为没有任何子节点的所有元素将
IsEmpty
属性设置为
false

    foreach (XElement childElement in
        from x in document.DescendantNodes().OfType<XElement>()
        where x.IsEmpty
        select x)
    {
        childElement.IsEmpty = false;
    }
foreach(中的XElement子元素)
从类型()的document.degenantNodes()中的x开始
其中x.i是空的
选择x)
{
childElement.IsEmpty=false;
}

XElement
值显式设置为空字符串应该有效。LINQ to XML已经将没有内容的节点(如
new-XElement(“foo”)
)与内容长度为零的节点(如
new-XElement(“foo”,string.Empty)
)区别对待,如上的文档所示

但是,如果这不起作用,或者您需要微调XML输出的其他方面,您可以派生一个自定义:

相关方法如下:

public override void WriteEndElement()
{
    inner.WriteFullEndElement(); // always write both start and close tags
}

我不能重现你的错误。这在4.0和3.5 netFX中都能正常工作:

namespace ExplicitXmlClosingTags
{
    using System.Xml;
    using System.Xml.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            const string ElementRoot = "RootElement";
            const string ElementChild = "ChildElement";
            const string AttributeChild = "ChildAttribute";

            XDocument xDoc = new XDocument();
            XElement root = new XElement(ElementRoot);
            XElement child = new XElement(ElementChild, string.Empty);
            root.Add(child);

            child.SetAttributeValue(AttributeChild, "AttrValue");
            xDoc.Add(root);

            XmlWriterSettings xws = new XmlWriterSettings();
            xws.Indent = true;
            using (XmlWriter xw = XmlWriter.Create("out.xml", xws))
            {
                xDoc.Save(xw);    
            }
        }
    }
}
制作以下内容:

<?xml version="1.0" encoding="utf-8"?>
<RootElement>
  <ChildElement ChildAttribute="AttrValue"></ChildElement>
</RootElement>

var document=XDocument.Parse(XMLData);
中的foreach(XElement子元素)
从类型()的document.degenantNodes()中的x开始
其中x.i是空的
选择x)
{
childElement.Value=“”;
}

试试这个吧。只需替换
childElement.IsEmpty=false带有
childElement.Value=”“

是的,这是上一篇文章的答案,但它不起作用。编辑答案以显示另一个方法,将
IsEmpty
设置为
false
。您编译了此代码吗?因为我在这里得到了一个错误消息,该消息是预期的,IsEmpty是只读属性。好奇你是怎么做到的:-@greenoldman你能做的,我测试过,就是把值改成string.Empty,这也会显式地关闭XMLelement@Dan“吃”这个的软件可能有点小错误,不能正确处理这个语法,我也遇到过这种情况。一般来说,是的,这不重要。类似Martinho在这里所说的例子:我有一个相同的问题-我有一个黑盒应用程序,需要完整格式的XML,并且使用修改后的XmlWriter工作得很好,以确保永远不会发送约定的空标记。谢谢你的想法(顺便说一句,您的代码编写不正确——在继承和编写XmlWriter的同时,实际上您应该继承、重写构造函数和相关方法),但是…我是个倒霉的家伙,它仍然不能按预期工作。我在我的原始帖子中添加了一个编辑。@macias:继承+合成是故意的。我写的MyWriter是一个。它适用于任何XmlWriter,而不仅仅是XmlTextWriter。我完全按照原样测试了它,并且它可以工作。我进行合成是为了获得XmlWriter的现有实现,我erit公开相同的接口。然后您应该从泛型类继承,该类的基类是XmlWriter。从另一个类继承而不使用它,同时组合是一个坏主意(通常情况下,它可能比这里更糟,因为构造函数可能非常重要)。(感谢您的回答).现在,这很有趣。我复制并粘贴了您的示例,但没有明确的结束标记(我也尝试了.Net 3.5)。哎呀,兼容性。。。
<?xml version="1.0" encoding="utf-8"?>
<RootElement>
  <ChildElement ChildAttribute="AttrValue"></ChildElement>
</RootElement>
 var document = XDocument.Parse(XMLData); 
                        foreach (XElement childElement in
                        from x in document.DescendantNodes().OfType<XElement>()
                        where x.IsEmpty
                        select x)
                        {
                            childElement.Value = "";
                        }