【问题标题】:What's so bad about building XML with string concatenation?使用字符串连接构建 XML 有什么不好?
【发布时间】:2010-06-14 01:33:45
【问题描述】:

What’s your favorite “programmer ignorance” pet peeve?的线程中,出现了如下答案,点赞量大:

Programmers who build XML using string concatenation.

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

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

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

【问题讨论】:

    标签: c# xml string


    【解决方案1】:

    你可能会得到无效的 XML,但直到你再次解析它才会发现 - 然后为时已晚。我很难学到这一点。

    【讨论】:

    • +1 - 通常是损坏的 XML 的使用者负责尝试寻找解决方法来解决损坏的问题。这就是为什么它会被贴上“讨厌鬼”的标签!
    • +1 - 就像我必须解析实体为数字的位置的一些“XML”。阿格勒。
    【解决方案2】:

    我认为可读性、灵活性和可扩展性是重要因素。考虑以下 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))));
    

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

    【讨论】:

    • 在创建一个大文档时,括号可能和 Lisp 程序一样多,但我不得不承认我也是这样做的。
    • 所以 this 被称为 Linq-to-Xml!天哪。
    • @Gregory Higley:如果您使用 StringBuilder,您可能会有大量的 ,或者 Lisp 的另一个名称?
    • @sixlettervariables:我听说这叫“尖括号汤”。
    【解决方案3】:

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

    只要替代方案是 XML 序列化和XmlDocument,我就可以看到支持字符串连接的简单论点。然而,自从XDocument 等。 al.,没有理由再使用字符串 concat 来构建 XML。请参阅 Sander 的回答,了解编写 XML 的最佳方式。

    XDocument 的另一个好处是 XML 实际上是一个相当复杂的标准,大多数程序员根本不理解它。我目前正在与一个向我发送“XML”的人打交道,其中包含未加引号的属性值、缺少结束标签、不正确的大小写敏感性和不正确的转义。但是因为 IE 接受它(作为 HTML),所以它一定是对的!唉……不管怎样,关键是字符串连接可以让你写任何东西,但是XDocument 将强制符合标准的 XML。

    【讨论】:

      【解决方案4】:

      我在 2006 年写了一篇博客文章 moaning about XML generated by string concatenation;简单的一点是,如果 XML 文档验证失败(编码问题、命名空间问题等)它不是 XML 并且 不能 被这样对待。

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

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

      鉴于 .NET 中的 XML 支持的丰富性与 XmlDocument,现在尤其是 XDocument,必须有一个非常有说服力的论据,使用这些库而不是基本的字符串连接恕我直言。 p>

      【讨论】:

        【解决方案5】:

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

        很明显,这些库会为您进行字符串操作,但读取/写入 xml 应该类似于将数据保存到数据库中或逻辑上类似的东西

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

            您需要手动转义字符串。这是正确的。但仅此而已吗?当然,您可以将 XML 规范放在您的办公桌上,并在每次构建 XML 字符串时考虑所有可能的极端情况时仔细检查。或者你可以使用封装了这些知识的库...

            【讨论】:

            • 你能详细说明一下吗?除了 &、、" 和 ' 等特殊字符之外,还有什么其他陷阱。它只是正确地嵌套标签吗?我还缺少什么?
            • @wsanville:与 [[CDATA]]、Unicode、命名空间、模式、处理指令有关。
            • @wsanville: <!-- did you know--this comment is invalid XML -->
            【解决方案8】:

            另一个反对使用字符串拼接的观点是,阅读代码时数据的层次结构不清晰。例如,在@Sander 的 Linq-to-XML 示例中,“product”元素属于哪个父元素,“title”属性适用于哪个元素等,这一点很清楚。

            【讨论】:

              【解决方案9】:

              正如您所说,使用字符串连接正确构建 XML 是很尴尬的,尤其是现在您拥有 XML linq,它允许简单地构建 XML 图并获得正确的命名空间等。

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

              但在处理复杂的 XML 图形时,人们常常忽略这些替代方案,而只使用 StringBuilder。

              【讨论】:

                【解决方案10】:

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

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

                【讨论】:

                  【解决方案11】:

                  我总是发现创建 XML 比阅读一个 XML 更像是一件苦差事。我从来没有掌握序列化的窍门——它似乎对我的课程不起作用——而不是花一周的时间试图让它工作,我可以在很短的时间内使用字符串创建一个 XML 文件并编写它出去。

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

                  我想这取决于程序员的偏好。当然,有不同的做事方式,当然,但是对于开发/测试/研究/调试,这会很好。但是,在将代码交给其他程序员之前,我也会清理我的代码并对其进行注释。

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

                  【讨论】:

                  • 一周?我不知道你做错了什么,但这是错误的。
                  【解决方案12】:

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

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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-04-20
                    • 2013-02-27
                    • 1970-01-01
                    • 2012-10-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多