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

Posted

技术标签:

【中文标题】使用格式化和缩进将 XElement 添加到 XML 文件【英文标题】:Add XElement to XML file with formatting and indenting 【发布时间】:2018-07-30 20:47:20 【问题描述】:

XML

源 XML

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

    <SecondElement>
    </SecondElement>
</Root>

所需的 XML

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

    <SecondElement>
    </SecondElement>

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

现在我的输出 XML 是

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

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

请注意,我需要使用 LoadOptions.PreserveWhitespace 加载 XML,因为我需要保留所有空格(客户需要)。 所需的输出是在“根”的最后一个子元素之后放置 2 个换行符并添加适当的缩进

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

任何想法如何实现这一点?

代码

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);

【问题讨论】:

你为什么关心空白?除了增加您存储的数据量之外,它什么也不做。 @DavidG 这是客户想要的 您可能无法使用额外的换行符做任何事情,但Indent 设置可能会使它看起来稍微好一些。 您可以将 cmets 添加到文件中,而不是额外的空白行,您可以在其中添加 cmets 指示子项的结束。我通常会在我的 xml 文件的每个部分添加开始注释和结束注释,以便于人类阅读。 【参考方案1】:

理想情况下,您应该向您的客户解释这实际上并不重要。

但是,如果您真的需要弄乱空格,我会注意到 XText 是您所需要的。这是另一个XObject,代表文本节点,可以作为内容的一部分穿插。这可能是比字符串操作更好的方法。

例如:

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"));

见this demo。

【讨论】:

谢谢!我完全忘记了 XText 类。【参考方案2】:

我的解决方案是在保存之前通过重新解析文档来美化。

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

【讨论】:

好。非常聪明! 据我所知,这将有效地从原始输入中释放空行。

以上是关于使用格式化和缩进将 XElement 添加到 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

将 XElement 添加到特定位置的另一个 XElement

如何将子元素作为解码字符串添加到 XElement?

如何在 XElement 上放置命名空间别名?如何将数据源添加到现有 RDL 文档?

XElement 会自动将 xmlns="" 添加到自身

粘贴到循环/if语句时如何使NetBeans自动格式化缩进?

从 XElement 创建带有名称空间和模式的 XML