2016-08-28 8 views
0

Эта программа считывает два HTML с моего сайта и затем анализирует каждый. Первый HTML (pass.html) не имеет в нем объявления DOCTYPE. pass.html обрабатывает обычно.DOM Parser зависает с HTML, имеющим объявление DOCTYPE

Второй HTML (freeze.html) имеет объявление DOCTYPE. freeze.html оценивается как fully valid службой валидации W3C. Однако, когда я пытаюсь разобрать 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

Вы должны вызвать setEntityResolver() в DocumentBuilder и предоставить средство распознавания, которое локально решает ваш DTD. В противном случае синтаксический анализ попытается загрузить его из веб-сайта, которое намеренно реагирует очень медленно, что приведет к его замораживанию. См. Http://stackoverflow.com/questions/2640825/how-to-parse-a-xhtml-ignoring-the-doctype-declaration-using-dom-parser?rq=1 – Alohci

ответ

1

следующие параметры проинструктировать парсер, чтобы не загружать внешние DTD из декларации DOCTYPE. Измените метод 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