Xml文档永远不应该作为String传递,如何激励

本文关键字:传递 何激励 String 文档 永远 不应该 Xml | 更新日期: 2023-09-27 17:59:10

当看到如下方法签名时,我感到非常不舒服:

public void foo(String theXml);

如果传递了一个以UTF-16XML声明开头的字符串,foofo会是什么?在我看来,XML应该被类型化为强XML类型,比如DOM树或字节数组。因此,foo应该重新声明为:

public void foo(Byte[] theXml);

通常,程序员在读取theXml时会不必要地假设它具有某种编码。通常只是希望文件库的默认值能够正确猜测。

我该如何激励我的同事

不兼容的文档头编码声明的动机太弱。(使用强类型或字节数组会阻止对文档进行天真的解析/修改。)我见过很多次由于这种错误而导致编码中断的情况。

Xml文档永远不应该作为String传递,如何激励

确保测试套件中有一个测试,如果在字符串中错误地处理XML,该测试将失败。如果解释问题没有动力,那么展示它的发生可能。。。

将XML作为String传递并不比将其作为byte[]传递更错误-如果输入已经解码,则可以很高兴地忽略处理指令中的解码提示。你担心对编码做出错误的假设,但如果你使用字符串,编码就不是问题,因为你不必解码任何东西。(当然,有人可能正在从原始字节构建字符串,并在这一点上做出错误的假设,当然将是一个问题。但话说回来,如果你采用byte[]参数,某人可能已经有了一个字符串,并使用不正确的字符集将其转换为字节。)

解析字符串输入并不比解析来自解码源(如java.io.ReaderSystem.IO.TextReader)的输入更奇怪(大多数XML解析器都允许您这样做),这就引出了另一个主题:我建议不要将未解析的XML完全作为字符串或字节数组传递-如果使用InputStream s(对于不知道编码的源)和Reader s(如果知道编码,或者由于某种原因不需要解码数据),您将获得更大的灵活性。您还可以获得这样的好处,即在解析整个文档之前,不需要将其驻留在内存中。

因此,取而代之的是:

public void foo(String theXml);
public void foo(byte[] theXml);
// Usage:
foo("<document />");
foo("<?xml version='1.0' encoding='UTF-8' ?><document />".getBytes("UTF-8"));

你会有:

public void foo(Reader source);
public void foo(InputStream source);
// Usage:
foo(new StringReader("<document />"));
foo(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8' ?><document />"
                             .getBytes("UTF-8")));

我想那些忽略编码重要性的人只会使用:foo(Encoding.Default.GetBytes(theString))来绕过你的建议。下一个可能会为你的类制作一个包装器,这样他们就可以再次使用string了。

我想,在某个时候,必须小心一些事情才能正确完成,而在你开始之前,保护那些不想写正确代码的人可能是一场失败的战斗。

实际上,就我个人而言,我总是发现我们在编码数据流中声明编码有点奇怪。但这是非常理论化的。

我实际上同意你的同事们的看法。这并不是一个很好的论据,除非你想节省内存,但在调试时它是不可读的。无论类型如何,在传递编码之前都应该对其进行检查。

然而,如果您创建或使用包装器,您可以认为代码更干净。