9

我有一个多模块 Maven 项目。在持久模块中,我有许多引用 DTD 的 XML 文件数据文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "myapp-data.dtd" >

<dataset>
      .....omitted for brevity....
</dataset>

DTD 与 XML 文件存储在同一目录中,甚至 Eclipse 也将这些 XML 文件报告为有效。

但是,当我运行应用程序时,DBUnit FlatXMLDataSet 会抛出 FileNotFound 异常,因为它无法定位 DTD。它显然是在根项目目录(例如 myproject/)中寻找 DTD。我原以为它会在与 XML 文件本身相同的目录中查找 DTD(例如 myproject/persist/target/test-data)。

查看 DBUnit 源代码,它有这样的说法“相对 DOCTYPE uri 是从当前工作目录中解析的”。

有什么好的方法来解决这个问题?

4

5 回答 5

9

好吧,我想我想通了。谢天谢地开源。

FlatXmlDataSetBuilder 上有一个将流传输到 DTD 的方法。这是一个公共方法 IMO,这太疯狂了,但话说回来,DBUnit 与 dtd 文件的 XML 不在同一个目录中,这太疯狂了。所以这里是:

String dtdResourceName = "classpath:test-data/myapp-data.dtd";      
Resource res = applicationContext.getResource(dtdResourceName);
builder.setMetaDataSetFromDtd(res.getInputStream());

现在,我将带有 dtd 的 DOCTYPE 声明留在与 XML 相同的目录中,并使用此 hack 来欺骗 DBUnit 做正确的事情。

于 2010-06-13T02:46:12.320 回答
3

始终使用正确的变量来访问特殊目录,因为多模块构建与本地构建具有不同的工作目录:

所以

  • 而不是mydir使用${project.basedir}/mydir
  • 而不是target/mydir使用${project.build.directory}/mydir
  • 而不是target/classes/mydir使用${project.build.outputDirectory}/mydir

这些变量总是评估为当前项目,无论它是从哪里调用的。这是POM 变量的概述(不完整,但最重要的东西在里面)

此外,如果您想进行一些交互式查询式调试,help:evaluate mojo会派上用场:

打电话

mvn help:evaluate

系统会提示您输入一个表达式。如果你输入一个表达式 eg ${project.build.plugins[0]},将列出指定元素的合并 dom


编辑:

好的,现在我想我看到了问题所在。那么为什么不直接引用 xml 中的目录:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "target/test-classes/myapp-data.dtd" >

我知道它不漂亮,但它应该可以工作,多模块与否。单元测试的当前目录始终是当前 ${project.basedir},而不是父项目目录。

于 2010-06-11T07:34:49.620 回答
1

您可以将 DTD 发布到 Web 服务器,然后将其 HTTP URL 放入 DOCTYPE,例如:

<!DOCTYPE myapp-data SYSTEM "-//The Owner//The Description//EN" "http://host/path/to/myapp-data.dtd">
于 2013-09-18T00:32:40.363 回答
0

打开 XML 文件时,请尝试使用“File”而不是“FileInputStream”。

例如:

ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(new File(fileName)));

这样,DTD 的相对路径应该从 XML 文件的目录开始。

如果你使用

ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(new FileInputStream(fileName)));

路径应该相对于当前工作目录。

于 2012-02-15T19:24:03.610 回答
0

它涉及一些丑陋的重复,但您可以将 DTD 的内容粘贴到相关的 XML 文件中,然后将它们用作内部 DTD

于 2013-09-18T00:34:42.887 回答