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

<?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是根据当前的工作双晶型解决的。”

解决此问题的好方法是什么?

有帮助吗?

解决方案

好的,我想我弄清楚了。谢天谢地,开源。

FlatxMldatAtaSetBuilder上有一种方法,该方法将流到达DTD。这是一个公共方法IMO真是太疯狂了,但是话又说回来,Dbunit看起来与DTD文件的XML相同的目录是疯狂的。所以这里是:

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

现在,我将DTD与XML相同的目录保留在DTD的目录中,并使用此技巧来欺骗Dbunit做正确的事。

其他提示

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

所以

  • 代替 mydir 利用 ${project.basedir}/mydir
  • 代替 target/mydir 利用 ${project.build.directory}/mydir
  • 代替 target/classes/mydir 利用 ${project.build.outputDirectory}/mydir

这些变量始终对当前项目进行评估,无论其何处。这是一个 POM变量的概述 (不完整,但最重要的东西在那里)

另外,如果您想进行一些交互式查询风格的调试, 帮助:评估Mojo 派上用场:

只是打电话

mvn help:evaluate

并会提示您表达表达。如果您输入表达式 ${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},而不是父级项目dir。

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

<!DOCTYPE myapp-data SYSTEM "-//The Owner//The Description//EN" "http://host/path/to/myapp-data.dtd">

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

例如:

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

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

如果您使用

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top