我试图构建一个XML文档的一部分,以便包含在最终文档中。
使用XDocument
时,我遇到了异常:
"This operation would create an incorrectly structured document."
这是因为我的片段有多个“根”节点。
由于该文件将被包含在一个更大的文档中,因此我的基本元素不会出现在最终文档的根目录中。
XDocument constsDocument = new XDocument(
new XComment($" Consts section generated on {DateTime.Now} "),
new XComment($" First group of constants. "),
FirstTextConsts(MyFirstCollection),
new XComment($" Refrigerant constants. "),
SecondTextConsts(MySecondCollection)
);
// To avoid xml file starting with <?xml version="1.0" encoding="utf-8"?> use stringbuilder and StreamWriter.
StringBuilder sb = new StringBuilder();
XmlWriterSettings xws = new XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent = true
};
using (XmlWriter xw = XmlWriter.Create(sb, xws))
{
constsDocument.Save(xw);
}
System.IO.StreamWriter file = new System.IO.StreamWriter(_outputFileName);
file.WriteLine(sb.ToString());
file.Close();
编辑1: 在文档创建过程中调用的两种方法(主要):
private static IEnumerable<XElement> FirstTextConsts(IEnumerable<MyClass> collection)
{
return collection.Select(r => new XElement("const",
new XAttribute("name", $"IDENTIFIER_{r.Id}"),
new XAttribute("translatable", "false"),
new XElement("text",
new XAttribute("lang","en"), r.Name)));
}
private static IEnumerable<XElement> SecondTextConsts(IEnumerable<MyClass> collection)
{
foreach (var obj in collection)
{
if (obj.SomeSelector)
yield return new XElement("const",
new XAttribute("name", $"IDENTIFIER_{r.Id}"),
new XAttribute("translatable", "false"),
new XElement("text",
new XAttribute("lang","en"), r.Name)));
if (obj.SomeOtherSelector)
yield return new XElement("const",
new XAttribute("name", $"IDENTIFIER_{r.Id}"),
new XAttribute("translatable", "true")
);
}
}
编辑2: 由于我需要使用XDocument的灵活性来构建一个多级xml文档,并且希望在不同级别上返回IEnumerable类型的帮助方法,因此我决定添加一个虚假的元素,在写入文件之前再将其删除:
XDocument constsDocument = new XDocument(
new XElement("root",
new XComment($" Consts section generated on {DateTime.Now} "),
new XComment($" First group of constants. "),
FirstTextConsts(MyFirstCollection),
new XComment($" Refrigerant constants. "),
SecondTextConsts(MySecondCollection)
)
);
在写入文件之前,我会去掉元素中的内容:
file.WriteLine(sb.ToString().Replace("<root>" + Environment.NewLine, "").Replace(Environment.NewLine + "</root>", ""));
XElement
实例的方法的可能解决方案。 - Keith Hall