DTD aus Classpath

Status
Nicht offen für weitere Antworten.

matches

Mitglied
Hallo,

ich habe ein Problem beim Validieren einer XML-Datei anhand einer DTD. Der Name der DTD ist im Header der XML-Datei angegeben.

Ich parse die XML-Datei mit einem DOM-Parser.

Der DOM-Parser sucht die DTD allerdings immer im selben Verzeichnis, in dem das XML liegt.

Wie kann ich dem Parser beibringen, dass er die DTD im Classpath suchen soll?


matches
 

Ladi

Mitglied
Hallo matches,

kannst Du vielleicht den Header deiner XML-Datei einbinden, damit wir Deine genaue Formulierung sehen können?

Gruß
Ladi
 

Ladi

Mitglied
Hallo matches,

habe ein wenig gegoogelt und habe eine Lösung gefunden. Diese heißt EntityResolver. Ein EntityResolver wird vom Parser aufgerufen um eine Entity zu finden und mann kann hier das implizite Verhalten übersteuern.

Beispiel:
DTD - im Programmverzeichnis abgelegt

Code:
<?xml version="1.0" encoding="UTF-8"?>

<!ELEMENT MyXml (MyNode)*>

<!ELEMENT MyNode (#PCDATA)>

XML - am beliebigen Platz abgelegt

Code:
<?xml version="1.0"?>
<!DOCTYPE MyXml SYSTEM "http://de.petera.xmlTest/MyXml.dtd">

<MyXml>
	<MyNode>node 1</MyNode>
	<MyNode>node 2</MyNode>
</MyXml>

Der folgende Kode gaukelt dem Parser einen InputStream mit der im Anwendungsverzeichnis abgelegten dtd immer, wenn er den System-Id "http://de.petera.xmlTest/MyXml.dtd" auflösen will.

Code:
package de.petera.xmlTest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XmlTest {

	public static void main(String[] args) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setValidating(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		builder.setEntityResolver(new MyResolver());
		Document doc = builder.parse(new File("d:/MyXml.xml"));
		
		NodeList elements = doc.getDocumentElement().getElementsByTagName("MyNode");
		
		for (int i=0;i<elements.getLength(); i++) {
			System.out.println(elements.item(i).getNodeValue());
		}
		
	}
	
}

class MyResolver implements EntityResolver {
	public InputSource resolveEntity(String publicId, String systemId)
			throws SAXException, IOException {

		if (systemId.equals("http://de.petera.xmlTest/MyXml.dtd")) {
			return new InputSource(new FileInputStream("MyXml.dtd"));
		} else {
			// use the default behaviour
			return null;
		}
	}
}

Gruß
Ladi
 

matches

Mitglied
Hallo,

so sieht der Header aus:

Code:
<?xml version="1.0" encoding="WINDOWS-1252"?>
<!DOCTYPE product PUBLIC "-//name//DTD specification//EN" "dsf.dtd">

matches
 

Ladi

Mitglied
Hallo matches,

für Antwort siehe meinen Vorherigen Post. In Deinem Fall würde die resolveEntity funktion halt den Attribut publicId auswerten.

Gruß
Ladi
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Fadi .classpath(XML) mit Java lesen XML & JSON 2

Ähnliche Java Themen

Neue Themen


Oben