View Javadoc

1   /*
2    * Copyright (c) 2002 Peter Antman, Teknik i Media  <peter.antman@tim.se>
3    *
4    * $Id: ElementUtil.java,v 1.1.1.1 2004/05/19 12:07:31 pra Exp $
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version
10   * 
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package org.backsource.utils.xml;
21  import java.util.List;
22  import java.util.Iterator;
23  import java.util.ArrayList;
24  
25  import org.w3c.dom.NodeList;
26  import org.w3c.dom.Node;
27  import org.w3c.dom.Element;
28  import org.w3c.dom.Text;
29  import org.w3c.dom.DocumentFragment;
30  /***
31   * <p>Utility methods to help working with Elements. 
32   *
33   * <p>To work in Nodes instead, see {@link DocumentUtil}
34   *
35   * @author <a href="mailto:pra@tim.se">Peter Antman</a>
36   * @version $Revision: 1.1.1.1 $
37   */
38  
39  public class ElementUtil{
40     private ElementUtil (){
41        
42     }
43     /***
44      * Get all element children of element.
45      *@returns a list, with no member if el has no element childs.
46      */
47     public static List getElements(Element element) throws XmlException{
48        ArrayList goodChildren = new ArrayList();
49        if (element == null) throw new XmlException("Element may nu be null");
50        
51        NodeList children = element.getChildNodes();
52        for (int i=0; i<children.getLength(); i++) {
53           Node currentChild = children.item(i);
54           if (currentChild.getNodeType() == Node.ELEMENT_NODE ) {
55              goodChildren.add((Element)currentChild);
56           }
57        }
58        return goodChildren;
59     }
60     
61     /***
62      * Get all element children of element whitch match tagName
63      *@returns a list, with no member if el has no element childs.
64      */
65     public static List getElementsByTagName(Element element, String tagName) throws XmlException{
66        ArrayList goodChildren = new ArrayList();
67        if (element == null) throw new XmlException("Element may nu be null");
68        // getElementsByTagName gives the corresponding elements in the whole 
69        // descendance. We want only children (direct descendents).
70        
71        NodeList children = element.getChildNodes();
72        for (int i=0; i<children.getLength(); i++) {
73           Node currentChild = children.item(i);
74           if (currentChild.getNodeType() == Node.ELEMENT_NODE && 
75               ((Element)currentChild).getTagName().equals(tagName)) {
76              goodChildren.add((Element)currentChild);
77           }
78        }
79        return goodChildren;
80     }
81  
82     /***
83      * Gets the child of the specified element having the
84      * specified name. If the child with this name doesn't exist
85      * then null is returned instead.
86      *
87      * @param element the parent element
88      * @param tagName the name of the desired child
89      * @return either the named child or null
90      */
91     public static Element getOptionalChild(Element element, String tagName)  throws XmlException{
92        return getOptionalChild(element, tagName, null);
93     }
94     
95     /***
96      * Gets the child of the specified element having the
97      * specified name. If the child with this name doesn't exist
98      * then the supplied default element is returned instead.
99      *
100     * @param element the parent element
101     * @param tagName the name of the desired child
102     * @param defaultElement the element to return if the child
103     *                       doesn't exist
104     * @return either the named child or the supplied default
105     */
106    public static Element getOptionalChild(Element element, String tagName, Element defaultElement) throws XmlException{
107       Iterator goodChildren = getElementsByTagName(element, tagName).iterator();
108 
109       if (goodChildren != null && goodChildren.hasNext()) {
110          Element child = (Element)goodChildren.next();
111          if (goodChildren.hasNext()) {
112             throw new XmlException
113                ("expected only one " + tagName + " tag");
114          }
115          return child;
116       } else {
117          return defaultElement;
118       }
119    }
120    /***
121     * Gets the child of the specified element having the specified unique
122     * name.  If there are more than one children elements with the same name
123     * and exception is thrown.
124     *
125     * @param element    The parent element
126     * @param tagName    The name of the desired child
127     * @return           The named child.
128     *
129     * @throws XmlException   Child was not found or was not unique.
130     */
131    public static Element getUniqueChild(Element element, String tagName) throws XmlException {
132       Iterator goodChildren = getElementsByTagName(element, tagName).iterator();
133       
134       if (goodChildren != null && goodChildren.hasNext()) {
135          Element child = (Element)goodChildren.next();
136          if (goodChildren.hasNext()) {
137             throw new XmlException
138                ("expected only one " + tagName + " tag");
139          }
140          return child;
141       } else {
142          throw new XmlException
143             ("expected one " + tagName + " tag");
144       }
145    }
146    /***
147     * Get the string content of the element. Merging all textnodes and cdata nodes.
148     */
149    public static String getContent(Element element) {
150        return getContent(element, null);
151    }
152    /***
153     * Get the string content of the element. Merging all textnodes and cdata nodes.
154     */
155    public static String getContent(Element element, String defaultStr) {
156       if (element == null)
157          return defaultStr;
158       
159       NodeList children = element.getChildNodes();
160       String result = "";
161       for (int i = 0; i < children.getLength(); i++)
162       {
163          if (children.item(i).getNodeType() == Node.TEXT_NODE ||
164              children.item(i).getNodeType() == Node.CDATA_SECTION_NODE)
165          {
166             result += children.item(i).getNodeValue();
167          }
168          else if( children.item(i).getNodeType() == Node.COMMENT_NODE )
169          {
170             // Ignore comment nodes
171          }
172          else
173          {
174             result += children.item(i).getFirstChild();
175          }
176       }
177       return result.trim();
178    }
179    /***
180     * Set the text content of this element. Owerwriting any prevous nodes.
181     */
182    public static void setContent(Element element, String content)  throws XmlException{
183        NodeList children = element.getChildNodes();
184        
185        // since a nod list is live, removal is pretty hard.
186        while (children.getLength()>0) {
187           element.removeChild( children.item(0));
188        } // end of while ()
189        
190        Text t = element.getOwnerDocument().createTextNode(content);
191        element.appendChild( t );
192    }
193    
194    /***
195     * Set element as a child element, removing all old elements.
196     */
197    public static void setElement(Element element, Element content) throws XmlException {
198       // since a nood list is live, removal is pretty hard.
199       NodeList children = element.getChildNodes();
200       while (children.getLength()>0) {
201          element.removeChild( children.item(0));
202       } //
203       
204       Node newNode = element.getOwnerDocument().importNode(content,true);
205       element.appendChild( newNode );
206    }
207    
208    /***
209     * Set DocumentFragment as a child element, removing all old elements.
210     */
211    public static void setElement(Element element, DocumentFragment content) throws XmlException {
212       // since a nood list is live, removal is pretty hard.
213       NodeList children = element.getChildNodes();
214       while (children.getLength()>0) {
215          element.removeChild( children.item(0));
216       } // end of while ()
217       
218       Node newNode = element.getOwnerDocument().importNode(content,true);
219       element.appendChild( newNode );
220    }
221 
222    /***
223     * Get attribute with name name from element, only return a non null value if the attribute was not  null and not an empty string.
224     * @return null if attribute as null or an empty string.
225     * @throws XmlException if element or name is null.
226     */
227    public static String getAttribute(Element element, String name) throws XmlException {
228       return getAttribute(element,name,null);
229    }
230 
231    /***
232     * Get attribute with name name from element, only return a non null value if the attribute was not  null and not an empty string, otherwise return defaultValue.
233     * @return default value if attribute as null or an empty string.
234     * @throws XmlException if element or name is null.
235     */
236    public static String getAttribute(Element element, String name, String defaultValue)throws XmlException{
237       if ( element == null) {
238          throw new XmlException("The element is not allowed to be null");
239       } // end of if ()
240       if ( name == null) {
241          throw new XmlException("The attribute name is not allowed to be null");
242       } // end of if ()
243       String value = element.getAttribute(name);
244       if ( value == null || "".equals( value.trim() )) {
245          value = defaultValue;
246       } // end of if ()
247       return value;
248    }
249 
250    /***
251     * Get the an attribute as an int
252     * @throws XmlException if the attribute could not be parsed.
253     */
254    public static int getAttributeAsInt(Element e, String name) throws XmlException {
255 
256        String v = e.getAttribute(name);
257        try {
258            return Integer.parseInt(v);
259        } catch (NumberFormatException ex) {
260            throw new XmlException("The attribute \"" + name
261                                   + "\" of element \"" + e.getTagName()
262                                   + "\" could not be parsed as an integer. The value is \""
263                                   + v + "\"");
264        }
265    }
266 
267    /***
268     * Get the an attribute as a long
269     * @throws XmlException if the attribute could not be parsed.
270     */
271    public static long getAttributeAsLong(Element e, String name) throws XmlException {
272 
273        String v = e.getAttribute(name);
274        try {
275            return Long.parseLong(v);
276        } catch (NumberFormatException ex) {
277            throw new XmlException("The attribute \"" + name
278                                   + "\" of element \"" + e.getTagName()
279                                   + "\" could not be parsed as a long. The value is \""
280                                   + v + "\"");
281        }
282    }
283 
284    /***
285     * Get the an attribute as a boolean.
286     * Handles null values correctly: No fall back on false, as (new Boolean(value)).booleanValue() does.
287     * @throws XmlException if the attribute could not be parsed.
288     */
289    public static boolean getAttributeAsBoolean(Element e, String name) throws XmlException {
290 
291        String v = e.getAttribute(name);
292 
293        if ("true".equalsIgnoreCase(v)) {
294            return true;
295        }
296 
297        if ("false".equalsIgnoreCase(v)) {
298            return false;
299        }
300 
301        throw new XmlException("The attribute \"" + name
302                               + "\" of element \"" + e.getTagName()
303                               + "\" could not be parsed as a boolean. The value is \""
304                               + v + "\"");
305    }
306 
307    /***
308     * Get the an attribute as a float.
309     * @throws XmlException if the attribute could not be parsed.
310     */
311    public static float getAttributeAsFloat(Element e, String name) throws XmlException {
312        String v = e.getAttribute(name);
313        try {
314            return Float.parseFloat(v);
315        } catch (NumberFormatException ex) {
316            throw new XmlException("The attribute \"" + name
317                                   + "\" of element \"" + e.getTagName()
318                                   + "\" could not be parsed as a float. The value is \""
319                                   + v + "\"");
320        }
321 
322    }
323 
324    public static void main(String[] args){
325       
326 
327    }
328 } // ElementUtil