Parsen von xml mit DOM, DOCTYPE-Element gelöscht wird
wie kommen dom mit java löscht doctype beim editieren von xml ?
habe diese xml-Datei :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE map[ <!ELEMENT map (station*) >
<!ATTLIST station id ID #REQUIRED> ]>
<favoris>
<station id="5">test1</station>
<station id="6">test1</station>
<station id="8">test1</station>
</favoris>
meine Funktion ist sehr einfach :
public static void EditStationName(int id, InputStream is, String path, String name) throws ParserConfigurationException, SAXException, IOException, TransformerFactoryConfigurationError, TransformerException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(is);
Element e = dom. getElementById(String.valueOf(id));
e.setTextContent(name);
//Write the DOM document to the file
Transformer xformer = TransformerFactory.newInstance().newTransformer();
FileOutputStream fos = new FileOutputStream(path);
Result result = new StreamResult(fos);
Source source = new DOMSource(dom);
xformer.setOutputProperty(
OutputKeys.STANDALONE,"yes"
);
xformer.transform(source, result);
}
es funktioniert, aber die doctype-Element gelöscht wird ! und ich habe gerade das ganze Dokument, aber ohne die doctype-Teil, der für mich wichtig ist, weil es mir erlaubt, abrufen von id !
wie halten wir den doctype ? warum macht man es löschen?
Ich habe versucht, viele Lösung mit outputkeys zum Beispiel oder omImpl.createDocumentType aber keiner von diesen hat funktioniert...
danke !
- Ich überrascht, dass Sie überhaupt etwas bekommen; Ihre XML ist ungültig.
- wirklich, aber wo ?
- Zwei Dinge: 1) doctype (Karte) passt nicht zu Ihrem root-element (favoris). 2) Das element "station" ist nicht deklariert. Sie sollten eine element-Deklaration für die station, und ändern Sie dann "favoris" "Karte" (oder ändern Sie den doctype und element-Deklaration).
- tut mir Leid, konnte Sie nur schreiben Sie es hier ? denn ich bin ein völlig fremder zu doc Art Dinge... :=)
- vielleicht sowas in der Art ? <!DOCTYPE favoris[<!ELEMENT-favoris (Bahnhof*) > <!ELEMENT station (#PCDATA)> <!ATTLIST station id id #REQUIRED> ]>
- +1 für die interessante Frage
Du musst angemeldet sein, um einen Kommentar abzugeben.
(Diese Antwort ist in einer Weise, die nur eine Ergänzung zu @Grzegorz Szpetkowski die Antwort, warum es funktioniert)
Verlieren Sie die doctype-definition, denn Sie verwenden die
Transform
Klasse erzeugt eine XSL-transformation. Es gibt keineDOCTYPE
Erklärung oder docytype definition Objekt/node im XSLT-Baum-Modell. Wenn ein parser übergibt das Dokument ein XSLT-Prozessor, der doctype-info ist verloren und kann deshalb nicht einbehalten oder vervielfältigt. XSLT bietet eine gewisse Kontrolle über die Serialisierung der output-Struktur, einschließlich dem hinzufügen einer<!DOCTYPE ... >
Deklaration mit public oder der system identifier. Die Werte für diese Bezeichner müssen im Voraus bekannt und kann nicht gelesen werden, von der input-Baum. Die Schaffung oder Beibehaltung einer eingebetteten DTD-oder entity-Deklarationen wird auch nicht unterstützt (obwohl eine Abhilfe für dieses Hindernis ist die Ausgabe als text mitdisable-output-escaping="yes"
).Zur Wahrung der DTD, die Sie benötigen, um die Ausgabe Ihres Dokuments mit einem XML-serializer statt XSL-transformation, wie Grzegorz bereits vorgeschlagen.
Ihrer XML-Eingabedatei ist nicht gültig. Das sollte sein:
Als @DevNull schrieb voll gültig, Sie können nicht schreiben
<station id="5">test1</station>
(allerdings für Java, es funktioniert jedenfalls auch mit diesem Thema).DOCTYPE
gelöscht wird in der Ausgabe-XML-Dokument:Empfinde ich nicht als Lösung für fehlende DTD noch nicht, aber als workaround können Sie eine externe DTD:
Ergebnis (Beispiel) Dokument:
EDIT:
Ich glaube nicht, dass es möglich ist, zu sparen, inline-DTD mit
Transformator
Klasse (vide hier). Wenn Sie nicht verwenden können externe DTD-Referenz, dann können Sie DOM Level 3LSSerializer
Klasse statt:Ausgabe mit wollte DTD (ich sehe keine option zum hinzufügen
standalone="yes"
mitLSSerializer
...):Ein weiterer Ansatz ist die Verwendung von Apache Xerces2-J
XMLSerializer
Klasse:Ergebnis:
@Grzegorz Szpetkowski hat eine gute Idee mit einer externen DTD. Jedoch, die XML ist immer noch ungültig, wenn Sie halten die Haltestelle/@id-Werte.
Jedes Attribut mit dem Typ "ID" kann nicht ein Wert, der beginnt mit einer Ziffer. Sie müssen noch etwas hinzufügen, wie z.B. "s" für die station:
LSSerializer
Klasse stattTransformer
Ansatz.Ich hatte fast das gleiche problem und fand diese die Werke mit transformieren. Es ist begrenzt, da es nur erlaubt den Verweis auf die dtd und es erfordert einige Arbeit, wenn der doctype des Dokuments kann variieren. Es war genug, in meinem Fall aber, ich brauchte nur zu fest die xhtml-doctype nach einer transformation.