在C#中保留XML属性之间的换行符

4

我有一个由用户输入的XML,需要向其中添加一些属性,然后将更改后的XML作为字符串返回。

现在的问题是,在属性之间忽略了空格。以下是我所说的示例:

我得到的XML:

<note day="12" 
      month="11"
      year="2002"
      to="Tove"
      from="Jani" 
      heading="Reminder">
</note>

我希望返回的内容是XML:

<note day="12" 
      month="11"
      year="2002"
      to="Tove"
      from="Jani" 
      heading="Reminder"
      body="Don't forget me this weekend!">
</note>

实际返回的XML:

<note day="12" month="11" year="2002" to="Tove" from="Jani" heading="Reminder" body="Don't forget me this weekend!">
</note>

这里是将xmlContent(用户定义的XML字符串)加载到XmlDocument类中的代码。
        XmlDocument xmlDocument= new XmlDocument();
        xmlDocument.PreserveWhitespace = true;
        xmlDocument.LoadXml(xmlContent);

但是当使用换行符分隔属性时,XmlDocument.PreserveWhitespace似乎无法工作。
为了从XmlDocument创建字符串,我使用以下代码:
 using (var sw = new StringWriter())
 {
     using (var xw = XmlWriter.Create(sw, settings))
     {
        xw.WriteString(xmlDocument.InnerXml);
     }
     string stringToOutput = sw.ToString();               
 }

1
欢迎来到 Stack Overflow。请编辑您的问题,将 XML 作为文本 内联显示,而不是作为图片。此外,您已经展示了读取 XML 的代码,但您还没有展示如何将其 写入 XML。一个 [mcve] 将会使帮助您变得更容易。 - Jon Skeet
谢谢您的回复。我已将XML更改为以文本形式显示,并添加了我编写XML的代码。 - Tycho
好的。首先,我建议使用xmlDocument.Save(sw) - 您不需要获取内部XML等。这不会解决问题,但在我看来,这是一种更好的方法。但是,XmlDocument.PreserveWhitespace是关于保留元素内容中的空格,而不是属性之间的空格。我不确定是否有一种方法可以保留属性的精确布局 :( - Jon Skeet
感谢您对保存部分的额外解释。我会按照您的建议进行更改。 - Tycho
Well,NewLineOnAttributes旨在创建新行。您是否需要实际保留所有现有格式,还是只需确保属性之间始终有新行即可? - Jon Skeet
显示剩余4条评论
2个回答

0

尝试查看设置.IndentChars。

var settings = new XmlWriterSettings() 
{
    IndentChars = "\r\n"
}

问题在于,当将XML字符串加载到XmlDocument中时,所有CR和NL字符都会被存储。除了那些在属性之间的字符。(\n\r甚至不会出现在由\n\r分隔的内联属性中) - Tycho

0

没有XML解析器会保留属性之间发生的确切空格。这只是外观而已。如果您有一个依赖于正确处理空格的应用程序,则该应用程序存在严重问题,您应修复它。

在StackOverflow上,我们经常看到两种问题。

(a)我们看到人们在不使用XML解析器的情况下读取XML,通常使用正则表达式。不可避免地,这些人只能处理格式与他们预期完全相同的传入XML。

(b)然后,我们看到人们试图生成格式与类别(a)中某个人预期完全相同的XML。这通常只能通过“手动格式化”XML而不是使用通用XML库来实现。

这些人忽略了XML的整个含义,即使用数据交换的标准格式,该格式由广泛可用的库支持,以降低成本。


2
我明白你的意思,但这个程序需要帮助用户构建XML。它通过向现有的XML添加一些属性来实现帮助。如果用户自己创建了一个将属性分隔为新行的XML,然后我的程序简单地忽略它们,那么就没有意义了。WPF是一个很好的例子,其中用户界面是由XAML定义的。假设用户想要使用我的程序向现有的XAML添加属性。如果我的程序完全搞乱了他们的缩进,那么不会有太多人会感到满意。 - Tycho
2
我怀疑有一些XML解析器可以做到这一点 - 就像Roslyn C#编译器能够保留精确的空格一样。在我看来,“我想能够修改文档而不完全改变所有格式,即使它在语义上没有意义”这个用例是非常合理的。然而,我不认为内置的XML API 处理这种用例。是否有其他可用于此的.NET库,我不知道。 - Jon Skeet
XML编辑器有这个要求,并通过进行自己的专门解析来解决它(它们还需要理解输入不规范的要求)。对于普通应用程序的通用XML解析,这将过于复杂(您需要保留单引号与双引号、十六进制与十进制字符引用、外部实体边界、属性顺序等区别)。这太困难了;尽管人们经常要求解决问题的部分解决方案,例如保留属性顺序是很好的。 - Michael Kay
应用场景:我的团队需要手动处理数十万行代码的XML文件,因此注释和空格对于在大型文件中导航非常有帮助,直到我们开发更多自动化工具。手动编辑并不理想,但在我们能够消除它之前,我们希望保留易于阅读的格式。 - SendETHToThisAddress

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接