Java tutorial
/* * Copyright (C) 2001 Christian Cryder [christianc@granitepeaks.com] * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: DOMUtil.java 114 2005-12-09 15:51:51Z christianc $ */ import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Iterator; import org.w3c.dom.Attr; import org.w3c.dom.CharacterData; import org.w3c.dom.Comment; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; /** * DOM related utility functions. */ public class DOMUtil { private static byte[] sep = System.getProperty("line.separator").getBytes(); /** * Find the first text descendent node of an element. * This recursively looks more than one level to search * for text in font nodes, etc. * * @param node The starting node for the search. * @return The text node or null if not found. */ public static Text findFirstText(Node node) { if (node instanceof Text) return (Text) node; for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { Text text = findFirstText(child); if (text != null) return text; } return null; } /** * Gets the first text descendent node of an element. * This recursively looks more than one level to search * for text in font nodes, etc. Throws a DOMException * if the Text object is not found. * * @param node The starting node for the search. * @return The text node or null if not found. * @throws DOMException if the Text object is not found */ public static Text getFirstText(Node node) { Text text = findFirstText(node); if (text == null) { String msg = "No child text mode found for element"; String id = getID(node); throw new DOMException((short) -1, msg + (id != null ? "; id=\"" + id + "\"" : "")); } return text; } /** * Automatically set text in a Node. Basically we find the first * Text node beneath the current node and replace it with a * CDATASection for the incoming text. All other Text nodes are * removed. Throws a DOMException if it's illegal to add a Text * child to the particular node. * * @param node the starting node for the search. * @param text the text to be set * @param allowMarkupInText whether to allow markup in text to pass through unparsed * @return the updated node * @throws DOMException if the Text object is not found */ public static Node setTextInNode(Node node, String text, boolean allowMarkupInText) { //start by setting the value in the first text node we find with a comment Comment comment = node.getOwnerDocument().createComment(""); Node newNode = null; //csc_092701.1 - support both encoded/unencoded text if (allowMarkupInText) newNode = node.getOwnerDocument().createCDATASection(text); else newNode = node.getOwnerDocument().createTextNode(text); //System.out.println ("newNode: "+newNode); Text textComp = DOMUtil.findFirstText((Element) node); //System.out.println ("textComp:"+textComp); if (textComp == null) { node.appendChild(comment); } else { Node parent = textComp.getParentNode(); parent.replaceChild(comment, textComp); } //now remove all the rest of the text nodes removeAllTextNodes(node); //now replace the comment with the newNode Node parent = comment.getParentNode(); parent.replaceChild(newNode, comment); //System.out.println ("parent: "+parent); //System.out.println ("result: "+DOMUtil.findFirstText((Element) parent)); //DOMUtil.printStackTrace(parent.getOwnerDocument().getDocumentElement()); return node; } /** * Remove all text nodes below this node * * @param node The starting node for the search. */ public static void removeAllTextNodes(Node node) { if (node == null) return; if (!node.hasChildNodes()) return; NodeList nl = node.getChildNodes(); for (int i = nl.getLength() - 1; i >= 0; i--) { Node n = (Node) nl.item(i); if (n instanceof Text) node.removeChild(n); else removeAllTextNodes(n); } } /** * Given a Node name, return the "id" attribute if it exists. * If it does not exist, return null instead. This is basically * just a convenience method to cast the node to element and * return the id from that. * * @param node the node name in question * @return the id value for the given node, if it exists. null if * doesn't */ public static String getID(Node node) { return getID(node, null); } /** * Given a Node, return the "id" attribute if it exists. * If it does not exist, return nullResponse instead. This is basically * just a convenience method to cast the node to element and * return the id from that. * * @param node the node in question * @param nullResponse the response to be returned if the id attribute * does not exist * @return the id value for the given node, if it exists. null if * doesn't */ public static String getID(Node node, String nullResponse) { String nodeName = nullResponse; if (node instanceof Element) { nodeName = ((Element) node).getAttribute("id"); } return nodeName; } protected static void print(OutputStream out, String s) { if (out != null) try { out.write(s.getBytes()); out.write(sep); } catch (IOException ioe) { } } }