在帖子What’s your favorite “programmer ignorance” pet peeve?中,会出现以下答案,其中包含大量的赞成票:
Programmers who build XML using string concatenation.
我的问题是,为什么通过字符串连接构建XML(例如C#中的StringBuilder
)不好?
我过去已经多次这样做了,因为对于我正在使用的数据结构/对象来说,它有时是从A点到B点的最快捷方式。到目前为止,我提出了一些原因,为什么这不是最好的方法,但有什么我忽略的?为什么要避免这种情况?
<?xml version="1.0"?>
)。这有害吗? StringBuilder
),这是否需要关注?据推测,像XmlWriter
这样的类也需要做一些字符串操作...... XmlSerializer
自动序列化/反序列化类。好的,我同意。 C#有很多有用的类,但有时我不想为一些非常快速的类创建类,比如写出日志文件或其他东西。这只是我懒惰吗?如果我正在做一些“真实”的事情,这是我处理w / XML的首选方法。答案 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)
“迅速从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来保存/读取你的文件,如果它都是乱七八糟的混乱,没有人会理解它是如何工作的。