Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

ElementList as Replacement for NodeList

DZone's Guide to

ElementList as Replacement for NodeList

· Java Zone
Free Resource

The single app analytics solutions to take your web and mobile apps to the next level.  Try today!  Brought to you in partnership with CA Technologies

If you have ever used the method Element.getElementsByTagName() which returns a org.w3c.dom.NodeList, you have probably had one of the following problems:

  • The NodeList is not a List
    So you can't use the useful methods of the List interface or of the Collections class.
  • The NodeList does not implements Iterable.
    So you cannot use the for each loop feature added in Java 5.
  • The method adds all the sub elements and not only the direct elements
  • The NodeList is a "list" of Node
    So to get the Element you need to cast the Node to Element.
  • The method returns the children in incorrect order.
  • No handy method to get the unique sub element.
That's why I've wrote ElementList and decided to put the code in public domain.
  • Implements List which make it iterable with for each loop
  • Only includes the direct child of the element
  • The get method returns objects of the class Element
  • By default includes all direct child elements
  • Preserves the order of the child elements
  • Includes a method to get the sub element when unique
If you don't want to follow the link here is the code:
/*
 * The code of this file is in public domain.
 */
package org.xins.common.xml;

import java.util.LinkedList;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.xins.common.text.ParseException;

/**
 * An ElementList is an NodeList with the following improvements:
 * <ul><li>Implements List which make it iterable with for each loop
 * </li><li>Only includes the direct child of the element
 * </li><li>Only includes the elements
 * </li><li>By default includes all direct child elements
 * </li><li>Preserves the order of the child elements
 * </li><li>Includes a method to get the sub element when unique
 * </li></ul>
 *
 * @author <a href="mailto:anthony.goubard@japplis.com">Anthony Goubard</a>
 *
 * @since XINS 3.0
 */
public class ElementList extends LinkedList {

   /**
    * The local name of the parent element.
    */
   private String parentName;

   /**
    * The local name of the child elements or * for all elements
    */
   private String childName;

   /**
    * Creates a list with all direct child element of the given element.
    *
    * @param element
    *    the parent element, cannot be <code>null</code>.
    */
   public ElementList(Element element) {
      this(element, "*");
   }

   /**
    * Creates a list with all direct child element with a specific local name of the given element.
    *
    * @param element
    *    the parent element, cannot be <code>null</code>.
    * @param childName
    *    the local name of the direct child elements that should be added to the list, cannot be <code>null</code>.
    */
   public ElementList(Element element, String childName) {
      parentName = element.getTagName();
      this.childName = childName;
      Node child = element.getFirstChild();
      while (child != null) {
         String newChildName = child.getLocalName();
         if (newChildName == null) {
            newChildName = child.getNodeName();
         }
         if (child.getNodeType() == Node.ELEMENT_NODE &&
                 (childName.endsWith("*") || childName.equals(newChildName))) {
            add((Element) child);
         }
         child = child.getNextSibling();
      }
   }

   /**
    * Gets the unique child of this list.
    *
    * @return
    *    the sub-element of this element list, never <code>null</code>.
    *
    * @throws ParseException
    *    if no child with the specified name was found,
    *    or if more than one child with the specified name was found.
    */
   public Element getUniqueChildElement() throws ParseException {
      if (isEmpty()) {
         throw new ParseException("No \"" + childName + "\" child found in the \"" + parentName + "\" element.");
      } else if (size() > 1) {
         throw new ParseException("More than one \"" + childName + "\" children found in the \"" + parentName + "\" element.");
      }
      return get(0);
   }

   /**
    * Gets the first child of this element.
    *
    * @return
    *    the sub-element of this element, or <code>null</code> if no element is found.
    */
   public Element getFirstChildElement() {
      if (isEmpty()) {
         return null;
      }
      return get(0);
   }
}

CA App Experience Analytics, a whole new level of visibility. Learn more. Brought to you in partnership with CA Technologies.

Topics:

Published at DZone with permission of Anthony Goubard, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}