2012-03-09 3 views
3

이 xhtml 파일을 xml로 구문 분석 할 때 이러한 간단한 파일에서 구문 분석을 수행하는 데 약 2 분이 걸립니다. Doctype 선언을 제거하면 즉각적으로 파싱된다는 것을 알게되었습니다. 이 파일이 파싱하는데 너무 오랜 시간이 걸리는 이유는 무엇입니까?끔찍한 성능 XML 문서로 Doctype이있는 XHTML 파일을 구문 분석

자바 예

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder bob = dbf.newDocumentBuilder(); 
Document template = bob.parse(new InputSource(new FileReader(xmlFile))); 

XHTML 예

<?xml version="1.0" encoding="UTF-8"?> 
<!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" 
    xmlns:ex="http://www.example.com/schema/v1_0_0"> 
    <head><title>Test</title></head> 
    <body> 
     <h1>Test</h1> 
     <p>Hello, World!</p> 
     <p><ex:test>Text</ex:test></p> 
    </body> 
</html> 

감사

편집 : 솔루션

실제로 그것이 이유에 대해 제공 한 정보를 바탕으로 문제를 해결하려면 일에서 일어나는

  • 내 DocumentBuilder를 말했 클래스 패스에서이 파일을 읽을 수있는 사용자 정의의 EntityResolver를 만든 src/main/resources 폴더
    1. 다운로드 DTD 관련 파일 : 전자 첫째, 나는이 기본 단계를했다 how to validate XML using java?

      뉴의 EntityResolver

      0 : 내 새의 EntityResolver

    를 사용하는 나는이 그래서 그렇게 대답 참조새의 EntityResolver를 사용하는 방법

    import java.io.IOException; 
    
    import org.xml.sax.EntityResolver; 
    import org.xml.sax.InputSource; 
    import org.xml.sax.SAXException; 
    
    public class LocalXhtmlDtdEntityResolver implements EntityResolver { 
    
        /* (non-Javadoc) 
        * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String) 
        */ 
        @Override 
        public InputSource resolveEntity(String publicId, String systemId) 
          throws SAXException, IOException { 
         String fileName = systemId.substring(systemId.lastIndexOf("/") + 1);  
         return new InputSource( 
           getClass().getClassLoader().getResourceAsStream(fileName)); 
        } 
    
    } 
    

    : 자바 당신의 XHTML 파일이 지정된 DTD를 따르는 것을 확인하기 위해 지정된 DTD 및 그와 포함 된 파일을 다운로드

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(true); 
    DocumentBuilder bob = dbf.newDocumentBuilder(); 
    bob.setEntityResolver(new LocalXhtmlDtdEntityResolver()); 
    Document template = bob.parse(new InputSource(new FileReader(xmlFile))); 
    
  • +0

    다른 사람들이 지적했듯이, 파서는 인터넷에서 자원을 다운로드하려고 시도하고 있습니다. 이러한 엔터티를 [해결]해야합니다 (http://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilder.html#setEntityResolver%28org.xml.sax.EntityResolver%29). . 어떤 이유로 든 – McDowell

    +0

    이 솔루션은 나를 위해 작동하지 않을 수 있습니다. 그래서 방금 squid를 설치하고 추가했습니다. -Dhttp.proxyHost = localhost -Dhttp.proxyPort = 3128 – Leo

    답변

    2

    사실, 당신은 문서를 가지고있어서 다행입니다. W3C는 요청량을 처리 할 수 ​​없기 때문에 의도적으로 응답하지 않습니다. 파서에 로컬 복사본을 제공해야합니다.

    Java 세계에서 이것을 수행하는 일반적인 방법은 Apache/Oasis 카탈로그 확인자를 사용하는 것입니다.

    최신 버전의 Saxon에는 이러한 일반적으로 사용되는 DTD 및 엔티티 파일에 대한 기본 지식이 있으며 Saxon이 XML 파서를 제공하도록 허용하면 자동으로 로컬 복사본을 사용하도록 구성됩니다. XSLT 또는 XQuery를 사용하여 데이터를 처리하지 않더라도 Saxon Configuration 객체를 만들고 getSourceParser() 메서드를 호출하여 XMLReader를 가져올 수 있습니다.

    (아마도 이것은 DOM에서 벗어날 수있는 좋은 시간입니다.Java에서 XML을 처리하기위한 많은 선택 중에서 DOM은 아마도 최악 일 것입니다. 저수준 탐색 API를 사용해야하는 경우 JDOM 또는 XOM과 같은 적절한 API를 선택하십시오.