解析带DTD文档的XML文件时出错

onlinb41 2006-12-26 09:16:43
我的DTD文档如下:
<!ELEMENT students (student+)>
<!ELEMENT student (Name,Department,Class,Course+)>
<!ATTLIST student ID CDATA #REQUIRED>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Department (#PCDATA)>
<!ELEMENT Class (#PCDATA)>
<!ELEMENT Course (CName,ExamDate,Teacher,CMark,CTime,CType,Score)>
<!ELEMENT CName (#PCDATA)>
<!ELEMENT ExamDate (#PCDATA)>
<!ELEMENT Teacher (#PCDATA)>
<!ELEMENT CMark (#PCDATA)>
<!ELEMENT CTime (#PCDATA)>
<!ELEMENT CType (#PCDATA)>
<!ELEMENT Score (#PCDATA)>

在eclipse里可以生成对应的xml文件:
<?xml version="1.0" encoding="gb2312" standalone="no"?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student ID="103220533">
<Name>学生1</Name>
<Department>计算机系</Department>
<Class>网通班</Class>
<Course>
<CName>Java</CName>
<ExamDate>2006-12-29</ExamDate>
<Teacher>龚根华</Teacher>
<CMark>6</CMark>
<CTime>96</CTime>
<CType>主修</CType>
<Score>88</Score>
</Course>
</student>
</students>

然后我再用DOM对该xml文件进行解析:
DocumentBuilderFactory domfac;
DocumentBuilder docBuilder;
Document doc;
InputStream in;
Element root;
NodeList students;
domfac = DocumentBuilderFactory.newInstance();
try{
docBuilder = domfac.newDocumentBuilder();
in = new FileInputStream("student.xml");
doc = docBuilder.parse(in);
root = doc.getDocumentElement();
students = root.getChildNodes();
............
}catch(ParserConfigurationException e){
e.printStackTrace();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(SAXException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
............

调试时出现如下错误:
org.xml.sax.SAXParseException: Relative URI "student.dtd"; can not be resolved without a base URI.
at org.apache.crimson.parser.Parser2.fatal(Parser2.java:3182)
at org.apache.crimson.parser.Parser2.fatal(Parser2.java:3176)
at org.apache.crimson.parser.Parser2.resolveURI(Parser2.java:2758)
at org.apache.crimson.parser.Parser2.maybeExternalID(Parser2.java:2730)
at org.apache.crimson.parser.Parser2.maybeDoctypeDecl(Parser2.java:1129)
at org.apache.crimson.parser.Parser2.parseInternal(Parser2.java:489)
at org.apache.crimson.parser.Parser2.parse(Parser2.java:305)
at org.apache.crimson.parser.XMLReaderImpl.parse(XMLReaderImpl.java:442)
at org.apache.crimson.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:185)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:98)
at lin.xml.OperateXML.<init>(OperateXML.java:37)
at lin.xml.OperateXML.main(OperateXML.java:71)
Exception in thread "main" java.lang.NullPointerException
at lin.xml.OperateXML.getDate(OperateXML.java:53)
at lin.xml.OperateXML.main(OperateXML.java:72)

急呀~~~在线等,谢谢高手指点.真的不知道怎么解决此问题.
快~~!!!
...全文
424 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
e_ville 2007-01-02
  • 打赏
  • 举报
回复
大致的意思是这样的:
Eclipse项目的目录可以设置成源文件和Class文件单独存放(src目录和bin目录),也可以设置成都放在同一目录中。
假如说是前者,源文件放在src目录,Class文件放在bin目录,那么我们命令行执行的时候就要进入到bin目录执行,这个时候所有的其他相关文件都是相对于bin目录来说的,如果你放在项目的根目录里面(即与src和bin目录在同一目录下),命令行就会出错,但是eclipse可能不会出错,因为他的起始目录就是项目的根目录,所以能够保证找到相关的文件。
可以做个简单的测试:
新建一个Java项目,把源文件和Class文件设置成放置在单独的目录里,然后在项目根目录下随便放个文本文件(test.txt),然后写个主类来读这个文件。
// Test.java --
// 2007-01-02 12:18

import java.io.*;

public class Test {

public static void main(String[] args) {
try {
BufferedReader in = new BufferedReader(new FileReader("test.txt"));
String buf;

while((buf = in.readLine()) != null) {
System.out.println(buf);
}
}
catch(FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}

1. 使用Eclipse运行,可以正确运行,输出文件内容。
2. 命令行运行:抛出FileNotFoundException。
由此可见,两者的运行时上下文是不同的,所以LZ的问题应该也是这一类问题,可能具体不同,但都是由于运行时上下文不同造成的。

反过来,你把test.txt文件放在src目录里面(编译后会在bin目录里),这时来运行,命令行可以正确运行,Eclipse又抛出FileNotFoundException了。

================================
总结:Eclipse的运行时起始目录是Eclipse项目的根目录;命令行的话,当然你在哪个目录下执行命令,哪个目录就是起始目录了。

有问题的话不好意思哈!!!^_^
onlinb41 2007-01-02
  • 打赏
  • 举报
回复
Your XML document makes reference to a DTD through a relative URI or path and
the XML parser is unable to resolve this relative URI from the XML document
path, i.e. relatively to "d:/XMLTest/xml".

There are several solutions to your problem :

1. Simple: Make sure the DTD file can be found locally, relatively to the XML
file path. If necessary, if you are using a stream/reader as input, you can
use SAXBuilder.build(InputStream/Reader, String) or set the System ID in the
SAX InputSource to let the parser know where the XML document actually lies
(this corresponds to setting the "base URI" the parser is asking for).

2. More generic: Implement an org.xml.sax.EntityResolver and register it onto
SAXBuilder to request the parser to delegate to your application the
resolution of enternal entities. That way, you are free to store the DTD files
whereever you wish (e.g. in the application JAR) or manage a cache of
frequently accessed DTDs.

onlinb41 2007-01-02
  • 打赏
  • 举报
回复
谢谢e_ville,现在问题已经解决:
try{
docBuilder = domfac.newDocumentBuilder();
in = new FileInputStream("student.xml");
doc = docBuilder.parse(in);
root = doc.getDocumentElement();
.......

修改为:
try{
docBuilder = domfac.newDocumentBuilder();
url = this.getClass().getResource("student.xml");
doc = docBuilder.parse(new File(url.getFile()));

这样就行了.
现在散分喽!!
onlinb41 2007-01-02
  • 打赏
  • 举报
回复
感谢你的解答,不过,错误好像不是因为这个:
我的eclipse设置的是源代码放在src目录和class文件放在bin目录xml和dtd文件都放在了项目的根目录.但在eclipse是在这行代码的异常导致的:
in = new FileInputStream("./student.xml");
doc = docBuilder.parse(in);
org.xml.sax.SAXParseException: Relative URI "student.dtd"; can not be resolved without a base URI.
我在控制台测试是把所有源文件和xml、dtd文件都放在了同一个目录下,测试通过.
e_ville 2007-01-01
  • 打赏
  • 举报
回复
org.xml.sax.SAXParseException: Relative URI "student.dtd"; can not be resolved without a base URI.

这个应该是没有把DTD和XML文件放在正确的目录下面造成的,在你的XML文件中,类型声明是这样的:<!DOCTYPE students SYSTEM "student.dtd">
所以呢,DTD和XML应该放在同一目录下面。
onlinb41 2007-01-01
  • 打赏
  • 举报
回复
高手们,帮帮忙吧
onlinb41 2007-01-01
  • 打赏
  • 举报
回复
或者,能不能说一下,我该怎么做才不会在eclipse时报错.
onlinb41 2007-01-01
  • 打赏
  • 举报
回复
能不能换一种说法,听不太明白~~呵呵!
非常感谢
e_ville 2007-01-01
  • 打赏
  • 举报
回复
说明:我把所有原文件复制出来,在命令行里可以编译执行,同时也解析出了xml文件里的内容.
=============================
这就没问题了,有Eclipse里会出错,因为Eclipse运行时的起始目录和命令行执行不同!
onlinb41 2007-01-01
  • 打赏
  • 举报
回复
谢谢~~
但是我的xml和dtd文件是在同一层目录里.所以应该不是这个原因~~
说明:我把所有原文件复制出来,在命令行里可以编译执行,同时也解析出了xml文件里的内容.
但同样的原文件在eclipse里就会报这个错!!!!!
请问有什么解决办法??????
onlinb41 2006-12-27
  • 打赏
  • 举报
回复
怎么没人应呀~~~好急哦~~
小弟在此先谢过了
onlinb41 2006-12-26
  • 打赏
  • 举报
回复
哪位高手帮看一下,并没有什么内容,只是一个入门级的错误,但找不到解决办法~~~急呀~~

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧