Mega Code Archive

 
Categories / Java Tutorial / XML
 

Find the first text descendent node of an element

/*  * 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) {}     } }