缩进XML,但保持其他所有内容不变

时间:2016-01-13 01:13:53

标签: c# xml linq

我的第一个问题,请耐心等待。基本上,我的问题是: 我正在为内部语言构建XML IDE。它的一个特性应该是使用一些命令自动缩进XML。与Visual Studio等中的内容类似。

基本上我需要的是打开以下Xml:

<?xml version="1.0" encoding="UTF-8"?>
<note>
        <to>Tove</to>

    <from>Jani</from>
        <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>

</note>

分为:

<?xml version="1.0" encoding="UTF-8"?>
<note>
    <to>Tove</to>

    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>

</note>

这是缩进 - 但没有别碰。这是否可以在C#中从头编写算法,即使用LINQ XDocument或某些XmlWriter实现?

到目前为止,我已尝试过以下内容(来自What is the simplest way to get indented XML with line breaks from XmlDocument?

static public string Beautify(this XmlDocument doc)
{
    StringBuilder sb = new StringBuilder();
    XmlWriterSettings settings = new XmlWriterSettings
    {
        Indent = true,
        IndentChars = "  ",
        NewLineChars = "\r\n",
        NewLineHandling = NewLineHandling.Replace
    };
    using (XmlWriter writer = XmlWriter.Create(sb, settings)) {
        doc.Save(writer);
    }
    return sb.ToString(); 
}

但这会删除换行符并给我:

<?xml version="1.0" encoding="UTF-8"?>
<note>
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
</note>

提前感谢任何有意见或回答的人。

3 个答案:

答案 0 :(得分:4)

我尝试使用自定义标记替换所有换行符(例如<newline></newline>,通过现有的Beautify代码运行结果,然后再次使用正确的换行替换换行标记。

更新:考虑到这一点,您可能需要将\n\n替换为&#39; \ n&#39;,但您会得到一般的想法。

答案 1 :(得分:2)

基于Mark的好建议,这将美化XML字符串(但代码不是很漂亮):

class Program
{
    static void Main(string[] args)
    {
        string test = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<note>
    <to>Tove</to>

<from>Jani</from>
    <heading>Reminder</heading>
<body>Don't forget me this weekend!</body>

</note>";
        string output = Test.BeautifyXML(test);
        Console.Write(output);
        Console.ReadLine();
    }
}
static class Test { 
    static public string BeautifyXML(this string docString)
    {
        docString = Regex.Replace(docString.Replace("\r", "<r></r>").Replace("\n", "<n></n>"),@"\?>(<r></r><n></n>)*", "?>");
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(docString);
        StringBuilder sb = new StringBuilder();
        XmlWriterSettings settings = new XmlWriterSettings
        {
            Indent = true,
            IndentChars = "  ",
            NewLineChars = "\r\n",
            NewLineHandling = NewLineHandling.Replace
        };
        using (XmlWriter writer = XmlWriter.Create(sb, settings))
        {
            doc.Save(writer);
        }
        return Regex.Replace(sb.ToString().Replace("\r\n", ""), @"<r></r>( )*<n></n>", "\r\n").Replace("?>", "?>\r\n");
    }
}

输出:

<?xml version="1.0" encoding="utf-16"?>
<note>
  <to>Tove</to>

  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>

</note>

答案 2 :(得分:0)

这可能会为你做到这一点

而不是

NewLineHandling = NewLineHandling.Replace

使用

NewLineHandling = NewLineHandling.None

None设置告诉XmlWriter保持输入不变。当您不需要任何换行处理时,将使用此设置。