简体   繁体   English

使用格式和缩进将 XElement 添加到 XML 文件

[英]Add XElement to XML file with formatting and indenting

XML XML

Source XML源 XML

<!-- The comment -->
<Root xmlns="http://www.namespace.com">
    <FirstElement>
    </FirstElement>

    <SecondElement>
    </SecondElement>
</Root>

Desired XML所需的 XML

<!-- The comment -->
<Root xmlns="http://www.namespace.com">
    <FirstElement>
    </FirstElement>

    <SecondElement>
    </SecondElement>

    <ThirdElement>
        <FourthElement>thevalue</FourthElement>
    </ThirdElement>
</Root>

Now my output XML is现在我的输出 XML 是

<!-- The comment -->
<Root xmlns="http://www.namespace.com">
    <FirstElement>
    </FirstElement>

    <SecondElement>
    </SecondElement><ThirdElement><FourthElement>thevalue</FourthElement></ThirdElement>
</Root>

Note that I need to load the XML with LoadOptions.PreserveWhitespace as I need to preserve all whitespaces (desired by customer).请注意,我需要使用LoadOptions.PreserveWhitespace加载 XML,因为我需要保留所有空格(客户需要)。 The desired output is to put 2 newlines after the last child element of the "root" and add with the proper indent所需的输出是在“根”的最后一个子元素之后放置 2 个换行符,并添加适当的缩进

<ThirdElement>
    <FourthElement>thevalue</FourthElement>
</ThirdElement>

Any ideas how to realize this?任何想法如何实现这一点?

Code代码

var xDoc = XDocument.Load(sourceXml, LoadOptions.PreserveWhitespace); //need to preserve all whitespaces
var mgr = new XmlNamespaceManager(new NameTable());
var ns = xDoc.Root.GetDefaultNamespace();
mgr.AddNamespace("ns", ns.NamespaceName);

if (xDoc.Root.HasElements)
{
    xDoc.Root.Elements().Last().AddAfterSelf(new XElement(ns + "ThirdElement", new XElement(ns + "FourthElement", "thevalue")));

    using (var xw = XmlWriter.Create(outputXml, new XmlWriterSettings() { OmitXmlDeclaration = true })) //omit xml declaration
        xDoc.Save(xw);
}

Ideally, you should explain to your client that this really isn't important.理想情况下,您应该向您的客户解释这真的不重要。

However, if your really need to mess around with whitespace, i'd note that XText is what you need.但是,如果您真的需要处理空白,我会注意到XText正是您所需要的。 This is another XObject that represents text nodes and can be interspersed as part of your content.这是另一个表示文本节点的XObject ,可以作为内容的一部分散布。 This is probably a much better approach than string manipulation.这可能是比字符串操作更好的方法。

For example:例如:

doc.Root.Add(
    new XText("\n\t"),
    new XElement(ns + "ThirdElement",
        new XText("\n\t\t"),
        new XElement(ns + "FourthElement", "thevalue"),
        new XText("\n\t")),
    new XText("\n"));

See this demo .请参阅此演示

My solution is to beautify just before saving by reparsing the document.我的解决方案是在保存之前通过重新解析文档来美化。

string content = XDocument.Parse(xDoc.ToString()).ToString();
File.WriteAllText(file, content, Encoding.UTF8);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM