C# 如何使用LINQXML强制显式标记关闭?
这与以下问题相同: 但我使用的是NET4.0,答案不再有效 问题是我保存的标记实际上没有值,我的输出XML如下所示: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
但我需要的总是开始和结束标记,即
问题:怎么做
编辑
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 = "";
}