Wenn ich meine XML-Datei (Variable f) in dieser Methode analysiere, wird eine Fehlermeldung angezeigt
C: \ Dokumente und Einstellungen \ joe \ Desktop \ aicpcudev \ OnlineModule \ map.dtd (Das System kann den angegebenen Pfad nicht finden.)
Ich weiß, ich habe weder das dtd noch brauche ich es. Wie kann ich dieses Dateiobjekt in ein Dokumentobjekt analysieren, während DTD-Referenzfehler ignoriert werden?
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;
}
Antworten:
Ein ähnlicher Ansatz wie der von @anjanb vorgeschlagene
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; } } });
Ich habe festgestellt, dass die einfache Rückgabe einer leeren InputSource genauso gut funktioniert.
quelle
Versuchen Sie, Funktionen in der DocumentBuilderFactory festzulegen:
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, dass die Optionen spezifisch für die Parser-Implementierung sind. Hier ist eine Dokumentation für Xerces2, falls dies hilfreich ist.
quelle
load-external-dtd
) hat den Trick für mich gemacht - danke.dbf.setNamespaceAware(true);
load-external-dtd
Einstellung genug.Ich habe ein Problem gefunden, bei dem sich die DTD-Datei zusammen mit dem XML in der JAR-Datei befand. Ich habe das Problem anhand der folgenden Beispiele wie folgt gelöst:
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; } } });
quelle
Quell-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 zum Akzeptieren des obigen XML als String und Entfernen der 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>
quelle
Ich bin dieser Aussage misstrauisch; Enthält Ihr Dokument Entitätsreferenzen? Wenn ja, brauchen Sie auf jeden Fall die DTD.
Die übliche Methode, dies zu verhindern, ist die Verwendung eines XML-Katalogs, um einen lokalen Pfad für "map.dtd" zu definieren.
quelle
Hier ist ein anderer Benutzer, der das gleiche Problem hat: http://forums.sun.com/thread.jspa?threadID=284209&forumID=34
Benutzer ddssot auf diesem Beitrag 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 erwähnt weiter: "Wie Sie sehen können, wird der Entitätsauflöser aufgerufen, wenn der Parser auf die DTD trifft. Ich erkenne meine DTD mit ihrer spezifischen ID und gebe ein leeres XML-Dokument anstelle der echten DTD zurück, wodurch alle Überprüfungen gestoppt werden ..."
Hoffe das hilft.
quelle
Ich arbeite mit Sonarqube und Sonarlint für Eclipse hat mir gezeigt, dass nicht vertrauenswürdiges XML analysiert werden sollte, ohne externe Daten aufzulösen (Squid: S2755).
Ich habe es geschafft, es zu lösen mit:
factory = DocumentBuilderFactory.newInstance(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // If you can't completely disable DTDs, then at least do the following: // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities // JDK7+ - http://xml.org/sax/features/external-general-entities factory.setFeature("http://xml.org/sax/features/external-general-entities", false); // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities // JDK7+ - http://xml.org/sax/features/external-parameter-entities factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // Disable external DTDs as well factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" factory.setXIncludeAware(false); factory.setExpandEntityReferences(false);
quelle