2016-08-28 11 views
0

이 프로그램은 내 사이트에서 두 개의 HTML을 읽고 각각을 구문 분석합니다. 첫 번째 HTML (pass.html)에는 DOCTYPE 선언이 없습니다. pass.html이 정상적으로 파싱됩니다.DOM 파서는 DOCTYPE 선언이있는 HTML로 고정합니다.

두 번째 HTML (freeze.html) 에는 DOCTYPE 선언이 있습니다. freeze.html은 W3C 유효성 검사 서비스에서 fully valid 으로 판단됩니다. 그러나 freeze.html을 구문 분석하려고하면 프로그램이 멈 춥니 다 .parse(is)

무엇이 잘못입니까?

import java.io.InputStream; 
import java.net.URL; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.Document; 

class DOMCallFreezes { 
    public static void main(String[] args) throws Exception { 
     new DOMCallFreezes().main(); 
    } 

    void main() throws Exception { 
     demo("pass.html"); 
     demo("freeze.html"); 
    } 

    void demo(String htmlName) throws Exception { 
     final String baseUrl = "http://x19290.appspot.com/dom-no-good/"; 
     URL url = new URL(baseUrl + htmlName); 
     try (final InputStream is = url.openStream()) { 
      final Document doc = newDocumentBuilder().parse(is); 
      final DOMSource src = new DOMSource(doc); 
      final StreamResult dst = new StreamResult(System.out); 
      newTransformer().transform(src, dst); 
     } 
    } 

    DocumentBuilder newDocumentBuilder() throws Exception { 
     final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); 
     return f.newDocumentBuilder(); 
    } 

    Transformer newTransformer() throws Exception { 
     final TransformerFactory f = TransformerFactory.newInstance(); 
     return f.newTransformer(); 
    } 
} 

pass.html

<?xml version="1.0" encoding="US-ASCII"?> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>pass</title> 
</head> 
<body> 
    <h1>no DOCTYPE declaration</h1> 
    </body> 
</html> 

freeze.html는

<?xml version="1.0" encoding="US-ASCII"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
<head> 
<title>freeze</title> 
</head> 
<body> 
    <h1>has DOCTYPE declaration</h1> 
</body> 
</html> 
+0

귀하의 질문 내용은 귀하의 질문에 ** ** 귀하의 질문에, 단지 연결되어 있어야합니다. 질문에'freeze.html'을 넣으십시오. (몇 줄이 넘으면 문제가되는 정도의 작은 것을 얻을 때까지 그 부분을 제거하십시오 : [mcve]를 참조하십시오.) –

+0

DocumentBuilder에서 setEntityResolver()를 호출하고 DTD를 로컬에서 확인해야합니다. 그렇지 않으면 구문 분석은 의도적으로 매우 느리게 응답하는 웹 위치에서 다운로드하려고 시도하여 동결을 유발합니다. http://stackoverflow.com/questions/2640825/how-to-parse-a-xhtml-ignoring-the-doctype-declaration-using-dom-parser?rq=1 – Alohci

답변

1

다음 설정은 DOCTYPE 선언에서 외부 DTD를로드하지 파서를 지시합니다. 방법 변경 newDocumentBuilder() :

DocumentBuilder newDocumentBuilder() throws Exception { 
    final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); 
    f.setValidating(false); 
    f.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
    return f.newDocumentBuilder(); 
} 
+0

자세한 내용은 https : // jaxp를 참조하십시오. .java.net/1.5/JAXP1.5Guide.html – Djoerd