使用字符串连接构建XML有什么坏处?

时间:2010-06-14 01:33:46

标签: c# xml string

在帖子What’s your favorite “programmer ignorance” pet peeve?中,会出现以下答案,其中包含大量的赞成票:

Programmers who build XML using string concatenation.

我的问题是,为什么通过字符串连接构建XML(例如C#中的StringBuilder)不好?

我过去已经多次这样做了,因为对于我正在使用的数据结构/对象来说,它有时是从A点到B点的最快捷方式。到目前为止,我提出了一些原因,为什么这不是最好的方法,但有什么我忽略的?为什么要避免这种情况?

  1. 可能我能想到的最大原因是你需要手动转义字符串,大多数新程序员(甚至是一些有经验的程序员)都会忘记这一点。当他们测试它时,它会对他们有用,但是当有人抛出一个&他们在某处输入的符号。好的,我会买这个,但是很容易防止这个问题(SecurityElement.Escape命名一个)。
  2. 当我这样做时,我通常会省略XML声明(即<?xml version="1.0"?>)。这有害吗?
  3. 性能处罚?如果您坚持使用正确的字符串连接(即StringBuilder),这是否需要关注?据推测,像XmlWriter这样的类也需要做一些字符串操作......
  4. 有更优雅的生成XML的方法,例如使用XmlSerializer自动序列化/反序列化类。好的,我同意。 C#有很多有用的类,但有时我不想为一些非常快速的类创建类,比如写出日志文件或其他东西。这只是我懒惰吗?如果我正在做一些“真实”的事情,这是我处理w / XML的首选方法。

13 个答案:

答案 0 :(得分:28)

你最终可能会得到无效的XML,但在你再次解析它之前你不会发现 - 然后就太晚了。我很难学到这一点。

答案 1 :(得分:13)

我认为可读性,灵活性和可扩展性是重要因素。考虑下面的Linq-to-Xml:

XDocument doc = new XDocument(new XDeclaration("1.0","UTF-8","yes"),
   new XElement("products", from p in collection
    select new XElement("product",
        new XAttribute("guid", p.ProductId), 
        new XAttribute("title", p.Title),
        new XAttribute("version", p.Version))));

你能找到比这更容易的方法吗?我可以将它输出到浏览器,将其保存到文档,在几秒钟内添加属性/元素等等......只需添加几行代码即可。我可以毫不费力地用它做几乎所有事情。

答案 2 :(得分:5)

实际上,我发现字符串连接的最大问题不是第一次正确,而是在代码维护期间保持正确。通常,使用字符串concat完美编写的XML片段会更新以满足新的要求,并且字符串连接代码太脆弱了。

只要替代方案是XML序列化和XmlDocument,我就可以看到simple参数支持string concat。但是,从XDocument等开始。也就是说,没有理由再使用string concat来构建XML了。有关编写XML的最佳方法,请参阅Sander的答案。

XDocument的另一个好处是XML实际上是一个相当复杂的标准,大多数程序员根本就不理解它。我目前正在处理一个向我发送“XML”的人,其中包含不带引号的属性值,缺少结束标记,不正确的区分大小写以及不正确的转义。但是因为IE接受它(作为HTML),它必须是正确的!叹息......无论如何,重点是字符串连接可以让你写任何东西,但XDocument将强制符合标准的XML。

答案 3 :(得分:5)

我在2006年写了一篇博客文章moaning about XML generated by string concatenation;简单的一点是,如果XML文档无法验证(编码问题,命名空间问题等)它不是XML 不能被视为

我已经看到XML文档存在多个问题,这些问题可以直接归因于使用字符串连接手动生成XML文档,而且几乎总是围绕正确使用编码。

问问自己这个;我目前使用什么字符集编码我的文档('ascii7','ibm850','iso-8859-1'等)?如果我将UTF-16字符串值写入已手动声明为“ibm850”的XML文档中会发生什么?

鉴于.NET中使用XmlDocument的XML支持非常丰富,现在尤其是XDocument,对于而不是使用这些库而不是基本字符串连接IMHO,必须有一个非常引人注目的论点。

答案 4 :(得分:4)

我认为问题在于您不是将xml文件视为逻辑数据存储,而是将其作为编写字符串的简单文本文件。

很明显,这些库为你做了字符串操作,但是读/写xml应该类似于将数据保存到数据库或逻辑相似的东西

答案 5 :(得分:3)

如果您需要简单的XML,那就没关系。当xml变得更大或更复杂时,它只是字符串连接的可维护性破坏了。您在开发时或维护时付款。您的选择始终是您的 - 但历史表明维护总是更昂贵,因此任何使其更容易的事情都是值得的。

答案 6 :(得分:2)

您需要手动转义字符串。那就对了。但这就是全部吗?当然,您可以将XML规范放在桌面上,并在每次构建XML字符串时考虑每个可能的角落情况时仔细检查。或者你可以使用一个封装了这些知识的库......

答案 7 :(得分:2)

反对使用字符串连接的另一点是,在读取代码时,数据的层次结构不明确。例如,在@ Sander的Linq-to-XML示例中,“product”元素属于哪个父元素,“title”属性应用于哪个元素等等。

答案 8 :(得分:2)

wsanville,它的态度和你一样,为什么我们不得不花费这么多时间来重构那些难以维护且无法重用的可怕代码。

“迅速从A点到B点”。然后你必须改变一些事情......

不,谢谢,不是我的团队。

答案 9 :(得分:1)

正如你所说,使用字符串连接构建XML是很尴尬的,特别是现在你有了XML linq,它允许简单构建XML图形并且可以获得名称空间等。

显然上下文及其使用方式很重要,例如在日志示例中string.Format可以完全接受。

但是,当使用复杂的XML图并只使用StringBuilder时,人们常常忽略这些替代方案。

答案 10 :(得分:1)

主要原因是 DRY:不要重复自己。

如果使用string concat来执行XML,您将不断重复将字符串保存为有效XML文档的函数。所有验证都将重复或不存在。最好依赖于包含XML验证的类。

答案 11 :(得分:0)

也许它永远不会发生,但如果你的环境有一天会切换到XML 2.0怎么办?您的字符串连接XML在新环境中可能有效,也可能无效,但XDocument几乎肯定会做正确的事。

好的,这是一个范围,但特别是如果您的不符合标准的XML没有指定XML版本声明......只是说。

答案 12 :(得分:-1)

我总是发现创建一个XML比阅读其中一个更多的苦差事。我从来没有得到序列化的支持 - 它似乎永远不适用于我的类 - 而不是花费一周时间试图让它工作,我可以在很短的时间内使用字符串创建一个XML文件并编写它进行。

然后我使用XMLReader树加载它。如果XML文件读取不是有效的,我会返回并在保存例程中找到问题并进行纠正。但是在我得到一个有效的保存/加载系统之前,我拒绝执行关键任务工作,直到我知道我的工具是可靠的。

我想这归结为程序员偏好。当然,有不同的做事方式,当然,但对于开发/测试/研究/调试,这没关系。但是,在将其交给另一位程序员之前,我还会清理我的代码并对其进行评论。

因为无论你使用StringBuilder或XMLNodes来保存/读取你的文件,如果它都是乱七八糟的混乱,没有人会理解它是如何工作的。