문제

이 메소드에서 XML 파일 (변수 f)을 구문 분석하면 오류가 발생합니다.

C : 문서 및 설정 joe goodtop aicpcudev onlinemodule map.dtd (시스템에서 지정된 경로를 찾을 수 없음)

나는 DTD가 없거나 필요하지 않다는 것을 알고 있습니다. DTD 참조 오류를 무시 하면서이 파일 객체를 문서 개체에 구문 분석하는 방법은 무엇입니까?

private static Document getDoc(File f, String docId) throws Exception{
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(f);


    return doc;
}
도움이 되었습니까?

해결책

제안 된 것과 비슷한 접근법 @anjanb

    builder.setEntityResolver(new EntityResolver() {
        @Override
        public InputSource resolveEntity(String publicId, String systemId)
                throws SAXException, IOException {
            if (systemId.contains("foo.dtd")) {
                return new InputSource(new StringReader(""));
            } else {
                return null;
            }
        }
    });

빈 입력 소스를 반환하는 것이 단순히 효과가 있었습니까?

다른 팁

DocumentBuilDerfactory에서 기능을 설정해보십시오.

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setValidating(false);
dbf.setNamespaceAware(true);
dbf.setFeature("http://xml.org/sax/features/namespaces", false);
dbf.setFeature("http://xml.org/sax/features/validation", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

DocumentBuilder db = dbf.newDocumentBuilder();
...

궁극적으로 옵션은 파서 구현에만 해당된다고 생각합니다. 다음은 XERCES2에 대한 문서입니다 그것이 도움이된다면.

XML과 함께 DTD 파일이 JAR 파일에있는 문제를 발견했습니다. 다음과 같이 여기의 예제를 기반으로 문제를 해결했습니다.

DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new EntityResolver() {
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
        if (systemId.contains("doc.dtd")) {
             InputStream dtdStream = MyClass.class
                     .getResourceAsStream("/my/package/doc.dtd");
             return new InputSource(dtdStream);
         } else {
             return null;
         }
      }
});

나는 DTD가 없거나 필요하지 않다는 것을 알고 있습니다.

나는이 진술을 의심한다. 귀하의 문서에는 엔티티 참조가 포함되어 있습니까? 그렇다면 DTD가 필요합니다.

어쨌든, 이런 일이 발생하지 않도록하는 일반적인 방법은 XML 카탈로그를 사용하여 "map.dtd"의 로컬 경로를 정의하는 것입니다.

동일한 문제를 겪은 다른 사용자는 다음과 같습니다. http://forums.sun.com/thread.jspa?threadid=284209&forumid=34

해당 게시물의 사용자 DDSSOT가 말합니다

myDocumentBuilder.setEntityResolver(new EntityResolver() {
          public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId)
                 throws SAXException, java.io.IOException
          {
            if (publicId.equals("--myDTDpublicID--"))
              // this deactivates the open office DTD
              return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
            else return null;
          }
});

사용자는 "파서가 DTD를 쳤을 때 엔티티 리졸버가 호출됩니다. 특정 ID로 DTD를 인식하고 실제 DTD 대신 빈 XML 문서를 반환하여 모든 유효성 검사를 중지합니다."

도움이 되었기를 바랍니다.

소스 XML (DTD 포함)

<!DOCTYPE MYSERVICE SYSTEM "./MYSERVICE.DTD">
<MYACCSERVICE>
   <REQ_PAYLOAD>
      <ACCOUNT>1234567890</ACCOUNT>
      <BRANCH>001</BRANCH>
      <CURRENCY>USD</CURRENCY>
      <TRANS_REFERENCE>201611100000777</TRANS_REFERENCE>
   </REQ_PAYLOAD>
</MYACCSERVICE>

위의 XML을 문자열로 수락하고 DTD 선언을 제거하기위한 Java DOM 구현

public Document removeDTDFromXML(String payload) throws Exception {

    System.out.println("### Payload received in XMlDTDRemover: " + payload);

    Document doc = null;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {

        dbf.setValidating(false);
        dbf.setNamespaceAware(true);
        dbf.setFeature("http://xml.org/sax/features/namespaces", false);
        dbf.setFeature("http://xml.org/sax/features/validation", false);
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

        DocumentBuilder db = dbf.newDocumentBuilder();

        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(payload));
        doc = db.parse(is); 

    } catch (ParserConfigurationException e) {
        System.out.println("Parse Error: " + e.getMessage());
        return null;
    } catch (SAXException e) {
        System.out.println("SAX Error: " + e.getMessage());
        return null;
    } catch (IOException e) {
        System.out.println("IO Error: " + e.getMessage());
        return null;
    }
    return doc;

}

대상 XML (DTD 없음)

<MYACCSERVICE>
   <REQ_PAYLOAD>
      <ACCOUNT>1234567890</ACCOUNT>
      <BRANCH>001</BRANCH>
      <CURRENCY>USD</CURRENCY>
      <TRANS_REFERENCE>201611100000777</TRANS_REFERENCE>
   </REQ_PAYLOAD>
</MYACCSERVICE> 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top