多模块 Java/Maven 项目中 DBUnit 的 XML DTD 路径?
我有一个多模块 Maven 项目。在 persist 模块中,我有许多引用 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 是从当前工作字典解析的。”
有什么好方法来解决这个问题?
I have a multi-module maven project. Within the persist module I have a number of XML files data files that reference a DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "myapp-data.dtd" >
<dataset>
.....omitted for brevity....
</dataset>
The DTD is stored in the same directory with the XML files and even Eclipse reports these XML files as valid.
However, when I run the application, the DBUnit FlatXMLDataSet throws a FileNotFound exception because it cannot located the DTD. It is apparently looking for the DTD in the root project directory (e.g. myproject/). I would have expected it to look for the DTD in the same directory as the XML file itself (e.g. myproject/persist/target/test-data).
Looking at the DBUnit source code, it has this to say about it "Relative DOCTYPE uri are resolved from the current working dicrectory."
What's a good way to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好吧,我想我已经弄清楚了这一点。感谢上帝的开源。
FlatXmlDataSetBuilder 上有一个方法可以将流传送到 DTD。在我看来,这是一个公共方法,这很疯狂,但话又说回来,DBUnit 没有在与 dtd 文件的 XML 相同的目录中查找,这也很疯狂。现在,
我将 DOCTYPE 声明和 dtd 保留在与 XML 相同的目录中,并使用此 hack 来欺骗 DBUnit 做正确的事情。
OK, I think I figured this one out. Thank goodness for open source.
There is a method on FlatXmlDataSetBuilder that takes a stream to the DTD. It's crazy that this is a public method IMO, but then again, its crazy that DBUnit doesn't look in the same directory as the XML for the dtd file. So here it is:
Now I leave the DOCTYPE declaration with the dtd in the same directory as the XML and use this hack to fool DBUnit into doing the Right Thing.
始终使用正确的变量来访问特殊目录,因为多模块构建具有与本地构建不同的工作目录:
因此,
mydir
使用${project.basedir}/mydir
target/mydir
使用${project.build.directory}/mydir
target/classes/mydir
使用$ {project.build.outputDirectory}/mydir
这些变量始终评估当前项目,无论从何处调用。这是POM 变量概述(不完整,但最重要的内容都在其中) )
此外,如果您想做一些交互式查询式调试,help:evaluate mojo 派上用场:
只需调用
,系统就会提示您输入表达式。如果您输入表达式,例如
${project.build.plugins[0]}
,则将列出指定元素的合并 dom编辑:
好的,现在我想我看到了问题。那么为什么不直接引用 xml 中的目录:
我知道它不太漂亮,但它应该可以工作,无论是否是多模块。单元测试的当前目录始终是当前的 ${project.basedir},而不是父项目目录。
Always use the correct variables to access special directories, because multi-module builds have a different working directory than local builds:
So
mydir
use${project.basedir}/mydir
target/mydir
use${project.build.directory}/mydir
target/classes/mydir
use${project.build.outputDirectory}/mydir
These variables always evaluate to the current project, no matter where it is called from. Here is an Overview of POM variables (not complete but the most important stuff is in there)
Also, if you ever want to do some interactive query-style debugging, the help:evaluate mojo comes in handy:
just call
and you will be prompted for an expression. If you enter an expression e.g.
${project.build.plugins[0]}
, the merged dom for the specified element will be listedEDIT:
ok, now I think I see the problem. then why not just reference the directory in the xml:
I know it's not pretty, but it should work, multi-module or not. the current directory for unit tests is always the current ${project.basedir}, not the parent project dir.
您可以将 DTD 发布到 Web 服务器,然后将其 HTTP URL 放入 DOCTYPE,例如:
You could publish the DTD to a web server and then put its HTTP URL into the DOCTYPE, e.g.:
打开 XML 文件时尝试使用“File”而不是“FileInputStream”。
例如:
这样,DTD 的相对路径应该从 XML 文件的目录开始。
如果使用
路径应该相对于当前工作目录。
Try using "File" instead of "FileInputStream" when opening an XML file.
For example:
This way, relative path to DTD should start with directory of the XML file.
And if you use
path should be relative to current working directory.
它涉及一些丑陋的重复,但您可以将 DTD 的内容粘贴到相关 XML 文件中,然后将它们用作 内部 DTD。
It involves some ugly duplication, but you could paste the contents of the DTD into the XML file(s) in question and then use them as internal DTDs.