package javacodebook.xml.processing.dom.manipulate; import java.io.*; import org.w3c.dom.*; // das sind Xerces-spezifischen Klassen die benötig werden, da // deren Funktionsumfang vom W3C noch nicht spezifiziert ist. import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; /** * Die Klasse DOMParserUtil ist ausführbar und nimmt 2 Parameter entgegen. * und * wobei den Ort des Dokumentes personal.xml beschreibt und * ein Verzeichnis enthält, in das das manipulierte XML geschrieben werden soll. * Im Wesentlichen führt die Anwendung einige Dummy-Manipulation an dem XML-Dokument * durch. * Es sollen folgende Aktionen durchgeführt werden: * + Finde das erste Element namens 'person' mit einem Attribut namens id * das den Wert 'three.worker' hat. * + Lese den Wert des Subelementes namens 'email' aus und schreibe ihn * in die Standardausgabe * + Kopiere das person-Element 'three.worker' und setzte das Attribut 'id' auf * clone.three.worker und füge es wieder in das Dokument ein. * + Schreibe das Dokument unter dem Namen 'manipulated.xml' * in das Verzeichnis, das als 2. Argument übergeben wurde. */ public class DOMManipulator { private static final String USAGE = "\nBenutzerhinweis: javacodebook.xml.processing.dom.parse.DOMManipulator " + " \n\nwobei\n\n\n" + "die URI unter der das XML-Dokument 'personal.xml' zu finden ist \n" + "(z.B. %XML_CHAPTER_HOME%\\processing\\dom\\manipulate\\personal.xml). Und\n\n\n" + "das Verzeichnis ist, in das das manipulierte Dokument geschrieben werden \n" + "soll"; /** * * In der main-Methode werden die beiden Parameter und * ausgelesen, das entsprechende Dokument geparst und einige * Manipulation an dem Dokument durchgeführt, bevor es dann wieder * in das Zielverzeichnis geschrieben wird. * * @param args und */ public static void main(String[] args) { if (args.length != 2) { System.out.println(getUsage()); System.exit(1); } Document doc = null; String uri = args[0]; String target = args[1]; DOMManipulator dOMManipulator = new DOMManipulator(); // das Dokument wir von der URI geparst. try { doc = dOMManipulator.parse(uri); } catch (Exception e) { System.out.println("Probleme beim parsen der URI '" + uri + "' mit: " + e); } // Um das gewünschte Element zu finden müssen zunächst alle Element des Typs 'person' // gesucht werden. Sie werden in einem Objekt vom Typ NodeList als eine // Art Liste referenziert. NodeList personNodeList = doc.getElementsByTagName("person"); // Ein zusätzliches Element muss deklariert werden, über das das kopierte // Elemente später referenziert werden kann. Element personClone = null; // Für jedes der Elemente mit dem Namen person, über die über die personNodeList // iteriert werden kann, wird geprüft, ob ein Attribut namens id // mit dem Wert 'three.worker' existiert. for (int i = 0; i < personNodeList.getLength(); i++) { // Obwohl die item-Method nur ein Node-Objekt zurückliefert, // können wir sicher sein, dass es sich um ein Element handelt, // da die Methode getElementsByTagName nur Elemente zurückliefert. // Also kann hier auch bedenkenlos gecastet werden. Element personElement = (Element) personNodeList.item(i); // Der Wert des Attributs 'id' wird abgefragt. String id = personElement.getAttribute("id"); if (id.equals("three.worker")) { // falls der Attributwert 'three.worker' entspricht, // wird das Element geklont. Der boolsche parameter bestimmt, // ob das Element mit oder ohne Unterelementen geklont werden soll. // Wir wollen das Element mit samt allen Unterknoten klonen. personClone = (Element) personElement.cloneNode(true); // das Unterelement 'email' wird ausgelesen. Hier muss man wieder // über eine NodeList gehen. NodeList emailNodeList = personElement.getElementsByTagName("email"); Element emailElement = null; // wir wissen, dass es nur ein email-Element geben kann. Also holen wir uns das // erste Element der NodeList. if (emailNodeList.getLength() > 0) { emailElement = (Element) emailNodeList.item(0); } // Da man nicht direkt auf den Text innerhalb eines Elements zugreifen // kann, müssen zunächst die Text-Knoten unterhalb des email-Elements // geholt werden. Man kann sich nicht grundsätzlich // darauf verlassen, dass Text innerhalb eines Elements // immer in einem einzigen Text-Knoten abgelegt ist. Es kann durchaus // vorkommen, dass der Text über mehrere Text-Knoten verteilt ist. Deswegen an // dieser Stelle eine Iteration über alle Text-Knoten unterhalb des // email Elements. NodeList subNodesFromEmail = emailElement.getChildNodes(); for (int j = 0; j < subNodesFromEmail.getLength(); j++) { Node node = subNodesFromEmail.item(j); // Da sich noch Knoten anderer Art innerhalb des // email-Elements befinden könnten, prüfen wir, // ob es sich um einen Text-Knoten handelt. Falls ja // wird der Inhalt in die Standardausgabe geschrieben. if (node.getNodeType() == Node.TEXT_NODE) { System.out.println(node.getNodeValue()); } } } } // wir erstellen noch einen Kommentar Comment comment = doc.createComment( "Es folgt das geklonte und leicht manipuliert wieder eingefügte Element"); // zunächst wird das Attribut an dem Klon verändert. // An dieser Stelle könnten beliebige andere strukturelle und inhaltliche // Änderungen durchgeführt werden. personClone.setAttribute("id", "clone.three.worker"); // dann werden Kommentar und Klon an das Root-Element des Dokuments gehängt. doc.getDocumentElement().appendChild(comment); doc.getDocumentElement().appendChild(personClone); // Für die Serialisierung wird ein OutputFormat-Objekt benötigt. OutputFormat format = new OutputFormat(doc, "ISO-8859-1", true); // Es wird ein XMLSerializer auf Basis des FileWriter-Objektes // und des OutputFormat-Objekts instanziiert. try { XMLSerializer serial = new XMLSerializer(new FileWriter(target + "/manipulated.xml"), format); serial.serialize(doc); } catch (Exception e) { System.out.println("Fehler beim Schreiben des Dokumentes: " + e); } } /** * * Diese Methode parst auf apache-xerces-proprietäre Weise eine URI, und liefert eine * W3C-Document Implementierung zurück. * * @param uri * @return org.w3c.Document * @throws Exception */ public Document parse(String uri) throws Exception { org.apache.xerces.parsers.DOMParser parser = new org.apache.xerces.parsers. DOMParser(); parser.parse(uri); return parser.getDocument(); } public static String getUsage() { return USAGE; } }