Frage

Wenn ich meine XML-Datei (Variable f) in diesem Verfahren zu analysieren, ich erhalte eine Fehlermeldung

  

C: \ Dokumente und Einstellungen \ joe \ Desktop \ aicpcudev \ OnlineModule \ map.dtd (Das System kann den Weg nicht finden spezifiziert)

Ich weiß, ich habe nicht die dtd haben, noch habe ich es brauchen. Wie kann ich dieses File-Objekt in ein Dokument-Objekt analysieren, während DTD Referenzfehler ignorieren?

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;
}
War es hilfreich?

Lösung

Ein ähnlicher Ansatz auf der einen Vorschlag von @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;
            }
        }
    });

fand ich, dass einfach eine leere Input Rückkehr genauso gut funktioniert?

Andere Tipps

Versuchen Features auf dem Document Einstellung:

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();
...

Letztendlich denke ich, die Optionen an den Parser Implementierung spezifisch sind. Hier einige Dokumentation für Xerces2 , ob das hilft.

fand ich ein Problem, bei dem die DTD-Datei zusammen mit der XML in der JAR-Datei war. Ich löste das Problem auf der Grundlage der Beispiele hier, wie folgt: -

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;
         }
      }
});
  

Ich weiß, ich habe nicht die dtd haben, noch habe ich es brauchen.

Ich bin von dieser Aussage verdächtig; hat Ihr Dokument keine Entity-Referenzen enthalten? Wenn ja, müssen Sie auf jeden Fall die DTD.

Wie auch immer, der üblicher Weg, um dies zu verhindern, geschieht einen XML-Katalog wird mit einem lokalen Pfad für „map.dtd“ zu definieren.

hier ist ein weiterer Benutzer, der das gleiche Problem bekam: http: // Foren. sun.com/thread.jspa?threadID=284209&forumID=34

Benutzer ddssot auf diesem Posten sagt

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;
          }
});

Der Benutzer weiter erwähnt „Wie Sie sehen können, wenn der Parser die DTD trifft, wird das Unternehmen Resolver genannt. Ich meine DTD mit seiner spezifischen ID erkennen und zurückgeben ein leeres XML-Dokument anstelle des echten DTD, alle Validierung zu stoppen. .. "

Hope, das hilft.

Quelle XML (Mit 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>

Java DOM-Implementierung für über XML als String zu akzeptieren und Entfernen von DTD-Deklaration

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;

}

Ziel XML (ohne DTD)

<MYACCSERVICE>
   <REQ_PAYLOAD>
      <ACCOUNT>1234567890</ACCOUNT>
      <BRANCH>001</BRANCH>
      <CURRENCY>USD</CURRENCY>
      <TRANS_REFERENCE>201611100000777</TRANS_REFERENCE>
   </REQ_PAYLOAD>
</MYACCSERVICE> 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top