在C#中,将字符串格式化为XML的最佳方法是什么?

43

我正在使用C#创建一个轻量级编辑器,想知道将字符串转换为格式良好的XML字符串的最佳方法。我希望在C#库中有一个公共方法类似于"public bool FormatAsXml(string text, out string formattedXmlText)",但是事情可能没有那么简单吧?

具体来说,如果要生成下面的输出,方法"SomeMethod"应该是什么?

string unformattedXml;
string formattedXml;

unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>"
formattedXml = SomeMethod(unformattedXml);

Console.WriteLine(formattedXml);

输出:

<?xml version="1.0"?>
  <book id="123">
    <author>Lewis, C.S.</author>
    <title>The Four Loves</title>
  </book>
10个回答

74
string unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>";
string formattedXml = XElement.Parse(unformattedXml).ToString();
Console.WriteLine(formattedXml);

输出:

<book>
  <author>Lewis, C.S.</author>
  <title>The Four Loves</title>
</book>

ToString() 方法不会输出 XML 声明,但 Save() 方法会输出。

  XElement.Parse(unformattedXml).Save(@"C:\doc.xml");
  Console.WriteLine(File.ReadAllText(@"C:\doc.xml"));

输出:

<?xml version="1.0" encoding="utf-8"?>
<book>
  <author>Lewis, C.S.</author>
  <title>The Four Loves</title>
</book>

似乎Parse()方法无法解析没有XML声明的字符串。 - h-rai
CSHTML文件的方法是什么? - Karthic G

15

很遗憾,这不像 FormatXMLForOutput 方法那样容易,因为我们在谈论的是微软公司;)

无论如何,在.NET 2.0中,建议使用XMlWriterSettings类来设置格式,而不是直接在XmlTextWriter对象上设置属性。查看此MSDN页面以获取更多详细信息。它说:

"在.NET Framework 2.0版本中,建议使用XmlWriter.Create方法和XmlWriterSettings类创建XmlWriter实例。这使您能够充分利用本版本引入的所有新功能。有关更多信息,请参阅创建XML编写器."

以下是推荐方法的示例:

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = ("    ");
using (XmlWriter writer = XmlWriter.Create("books.xml", settings))
{
    // Write XML data.
    writer.WriteStartElement("book");
    writer.WriteElementString("price", "19.95");
    writer.WriteEndElement();
    writer.Flush();
}

13

使用新的System.Xml.Linq命名空间(System.Xml.Linq程序集),你可以使用以下内容:

string theString = "<nodeName>blah</nodeName>";
XDocument doc = XDocument.Parse(theString);

您也可以使用以下方式创建片段:

string theString = "<nodeName>blah</nodeName>";
XElement element = XElement.Parse(theString);

如果字符串还不是XML格式,您可以像这样处理:

string theString = "blah";
//creates <nodeName>blah</nodeName>
XElement element = new XElement(XName.Get("nodeName"), theString); 

需要注意的是,在最后一个示例中,XElement将对提供的字符串进行XML编码。

我强烈推荐使用新的XLINQ类。它们比大多数现有的XmlDocument相关类型更轻巧、更易于使用。


9

假设您只想重新格式化XML文档以将新节点放在新行上并添加缩进,则如果您使用的是.NET 3.5或更高版本,则最佳解决方案是使用XDocument解析然后输出,例如:

string unformattedXml;
string formattedXml;

unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>";
formattedXml = System.Xml.Linq.XDocument.Parse(unformattedXml).ToString();

Console.WriteLine(formattedXml);

很整洁,是吧?

然后,这将重新格式化XML节点。

以前的框架需要更多的工作来完成此操作,因为没有内置函数来重新计算空格。

事实上,使用Linq之前的类来完成此操作会更麻烦:

string unformattedXml;
string formattedXml;

unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>";
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(unformattedXml);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.Xml.XmlWriter xw = System.Xml.XmlTextWriter.Create(sb, new System.Xml.XmlWriterSettings() { Indent = true });
doc.WriteTo(xw);
xw.Flush();
formattedXml = sb.ToString();
Console.WriteLine(formattedXml);

5

看起来你想将XML加载到XmlTextWriter对象中,并设置格式和缩进属性:

writer.Formatting = Formatting.Indented;
writer.Indentation = 1;
writer.IndentChar = '\t';

我过去曾经使用过这种方法(相对容易),但是随着.NET 2.0及以后的版本,微软现在建议使用XmlTextWriterSettings类,以便您可以利用2.0和3.5中添加的新功能。请参见我的答案中的链接。 - Ash

4

Jason的方法是最简单的。以下是该方法:

private static string FormatXmlString(string xmlString)
{
    System.Xml.Linq.XElement element = System.Xml.Linq.XElement.Parse(xmlString);
    return element.ToString();
}

2
干脆把那个变成一行代码。 - mpen

2
如果您只需要转义XML字符,以下内容可能会有所帮助:
string myText = "This & that > <> &lt;";
myText = System.Security.SecurityElement.Escape(myText);

1
在 Framework 4.0 中,它很简单。
var unformattedXml = "<?xml version=\"1.0\"?><book><author>Lewis, C.S.</author><title>The Four Loves</title></book>";
var xdoc = System.Xml.Linq.XDocument.Parse(unformattedXml);
var formattedXml = (xdoc.Declaration != null ? xdoc.Declaration + "\r\n" : "") + xdoc.ToString();
Console.WriteLine(formattedXml);

这将添加所需的缩进,并保留Xml声明
<?xml version="1.0"?>
<book>
  <author>Lewis, C.S.</author>
  <title>The Four Loves</title>
</book>

0

这个字符串是有效的 XML 吗?你是指如何将 XML 字符串转换为 XML 文档吗?如果是这样,请执行以下操作:

XmlDocument xml = new XmlDocument();

xml.LoadXml( YourString );

1
你没有看到其他两三个给出完全相同答案的回答吗? - cjk

0

System.Xml.Linq.XElement.ToString() 自动格式化!

XElement formattedXML = new XElement.Parse(unformattedXmlString);
Console.WriteLine(formattedXML.ToString());

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