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

时间:2011-06-14 12:36:33

标签: c# java xml

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

public void foo(String theXml);

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

public void foo(Byte[] theXml);

通常,当阅读theXml具有特定编码时,程序员将不必要地假设。通常只是希望文件库的默认值能正确猜测。

我如何向同事推荐这个?

不兼容的文档标题编码声明太弱了。 (使用强类型或字节数组会阻止对文档进行简单的解析/修改。)我已经多次看到由于这种错误导致编码中断的情况。

4 个答案:

答案 0 :(得分:7)

确保测试套件中存在测试,如果在String中错误地处理XML,则测试将失败。如果解释问题没有激励,可能会发生这种情况......

答案 1 :(得分:6)

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

解析字符串输入并不比解析来自像java.io.ReaderSystem.IO.TextReader这样的解码源的输入(大多数XML解析器允许你这样做)并不奇怪,这将我们带到另一个主题: I建议不要将未解析的XML作为字符串或字节数组完全传递 - 如果您使用InputStream(对于您不知道编码的源)和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")));

答案 2 :(得分:0)

我认为忽略编码重要性的那些只会使用:foo(Encoding.Default.GetBytes(theString))解决您的建议。而下一个可能会为您的课程创建一个包装器,以便他们可以再次使用string

我想在某些时候必须注意让一些事情做得正确,并且防止那些不想写正确代码的人可能会在你开始之前失去战斗。

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

答案 3 :(得分:0)

我实际上同意你的同事。除非你想节省内存但是在调试中它是不可读的,否则对此没有什么好的论据。无论类型如何,都应该在传输之前检查编码。

如果您创建或使用包装器,则可以认为代码更清晰。