2015-09-03 61 views
1

我有一个JDOM 1.1的问题,我找不到解决方案,更不用说一个原因了(我已经搜索了一段时间......)。我有一个非常简单的设置小测试程序:为什么JDOM的SAXBuilder会导致java.net.SocketException?

  1. 创建一个新的File对象,已经存在,我打算解析。这是一个XHTML文件。
  2. 创建一个新的SAXBuilder与验证设置为false
  3. 创建一个新的Document对象,应当由SAXBuilder

我的问题

不知怎的,充满了问题&,builder.build(file)导致java.net.SocketException留言Permission denied: connect。我不明白为什么它甚至需要套接字连接,除了验证,我在SAXBuilder的构造函数中将其设置为false。所以,我的问题是:有谁能告诉我可能是什么原因造成的异常?更具体地说,它试图连接到什么地方,我如何防止它?

谢谢!

JAVA代码

public static void main(String[] args) { 
File file = new File("C:\\Users\\ABC\\Desktop\\test.xhtml"); 
SAXBuilder builder = new SAXBuilder(false); 
try { 
    Document document = builder.build(file); 
    XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); 
    outputter.output(document, System.out); 
} catch (JDOMException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
} 

的XHTML文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
<html xmlns="http://www.w3.org/1999/xhtml"> 
 

 
<head> 
 
    <title>Title of document</title> 
 
</head> 
 

 
<body> 
 
    some content 
 
</body> 
 

 
</html>

堆栈跟踪

java.net.SocketException: Permission denied: connect 
at java.net.DualStackPlainSocketImpl.connect0(Native Method) 
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) 
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) 
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) 
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) 
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) 
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
at java.net.Socket.connect(Socket.java:579) 
at java.net.Socket.connect(Socket.java:528) 
at sun.net.NetworkClient.doConnect(NetworkClient.java:180) 
at sun.net.www.http.HttpClient.openServer(HttpClient.java:432) 
at sun.net.www.http.HttpClient.openServer(HttpClient.java:527) 
at sun.net.www.http.HttpClient.<init>(HttpClient.java:211) 
at sun.net.www.http.HttpClient.New(HttpClient.java:308) 
at sun.net.www.http.HttpClient.New(HttpClient.java:326) 
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:996) 
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:932) 
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:850) 
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:637) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1290) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1257) 
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:263) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1164) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1050) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:964) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) 
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) 
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) 
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) 
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649) 
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:489) 
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:847) 
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:826) 
at test.xmlparser.Main.main(Main.java:51) 
+0

像往常一样,写下来的问题帮助后不久,解决它自己。对于遇到同一问题的人: 问题是第一行: '<!DOCTYPE html PUBLIC“ - // W3C // DTD XHTML 1.0 Transitional // EN”“http://www.w3.org /TR/xhtml1/DTD/xhtml1-transitional.dtd“>' 只需将其删除,例如通过一些预处理器,XMLOutputter将用一个标准的xml声明替换它。 – aebblcraebbl

回答

0

问题是DTD用于验证XHTML文档。正如您在评论中发现的那样。

在XML中,DTD不仅用于验证XHTML文档结构,还用于提供任何需要扩展的实体引用(请考虑nbsp;等)。

我在回答这个问题的同时,知道自己已经有了答案的原因,是因为您的答案是部分答案,并不是一个好的解决方案。删除XHTML文档的doctype将在稍后导致其他问题。

不幸的是,正确的解决方案是让DTD文档可用于您的解析器。对于标准的XML解析,典型的方法是从URL中提取DTD(这正是JDOM在这里所要做的 - 实际上,当JDOM要求它解析文档时,xerces正在尝试这么做)。如果你没有网络连接,那么你可能真的很难,就像你发现的那样。但是,即使你有网络连接,如果XML是XHTML,你就有一个双重问题 - W3C的人有意破坏你的代码!

有一定的参考,你应该看到:

  1. W3C's excessive DTD block
  2. How to bypass the request to the internet for DTDIBM Developerworks
  3. 一些指令使用目录:XML-Catalog
  4. 一个小项目,我开始了一段时间后说“的行为以及缓存文件:Resolver < - 这对你来说不是很有用,因为你没有网络,但它有一些关于这个问题的文档。

如果你有你想如何解决DTD的想法,然后你可以提供的EntityResolver到JDOM SAXBuilder的有:setEntityResolver()