View Javadoc
1   package net.sf.logdistiller.xml;
2   
3   /*
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  import java.util.Iterator;
18  import java.util.NoSuchElementException;
19  import org.w3c.dom.Element;
20  import org.w3c.dom.Node;
21  import org.w3c.dom.NodeList;
22  
23  /**
24   * Miscellaneous utilities for DOM.
25   */
26  public class DOMUtils
27  {
28      private DOMUtils()
29      {
30      }
31  
32      public static String getPCDATAByTagName( Element elmt, String tagName )
33      {
34          return getPCDATAByTagName( elmt, tagName, false );
35      }
36  
37      public static String getPCDATAByTagName( Element elmt, String tagName, boolean normalize )
38      {
39          Iterator<Element> iter = getChildElementsByTagName( elmt, tagName );
40          if ( !iter.hasNext() )
41          {
42              return null;
43          }
44          return getPCDATA( (Element) iter.next(), normalize );
45      }
46  
47      /**
48       * Computes the resulting string of a <code>#PCDATA</code> element: it can consist in the XML document of a
49       * combination of nodes Text, EntityReference and CDATASection, with Comment.
50       *
51       * @param normalize normalize the element before computing?
52       */
53      public static String getPCDATA( Element element, boolean normalize )
54      {
55          if ( normalize )
56          {
57              element.normalize();
58          }
59          StringBuffer buff = new StringBuffer();
60          NodeList list = element.getChildNodes();
61          int len = list.getLength();
62          for ( int i = 0; i < len; i++ )
63          {
64              Node n = list.item( i );
65              switch ( n.getNodeType() )
66              {
67                  case Node.TEXT_NODE:
68                  case Node.CDATA_SECTION_NODE:
69                      buff.append( n.getNodeValue() );
70                      break;
71                  case Node.ENTITY_REFERENCE_NODE:
72                      buff.append( n.getFirstChild().getNodeValue() );
73                      break;
74                  case Node.COMMENT_NODE:
75                      break; // ignore comments
76                  default: // should not occur if really #PCDATA
77                      throw new IllegalArgumentException( "element '" + element.getNodeName()
78                          + "' is not #PCDATA because it " + "contains a " + getNodeTypeAsString( n ) + " node" );
79              }
80          }
81          return buff.toString();
82      }
83  
84      public static String getPCDATA( Element elmt )
85      {
86          return getPCDATA( elmt, false );
87      }
88  
89      public static Iterator<Element> getChildElementsByTagName( Element element, String tagName )
90      {
91          return new ElementIterator( element.getChildNodes(), tagName );
92      }
93  
94      public static String getNodeTypeAsString( Node node )
95      {
96          int type = node.getNodeType();
97          switch ( type )
98          {
99              case Node.ELEMENT_NODE:
100                 return "Element";
101             case Node.ATTRIBUTE_NODE:
102                 return "Attribute";
103             case Node.TEXT_NODE:
104                 return "Text";
105             case Node.CDATA_SECTION_NODE:
106                 return "CDATASection";
107             case Node.ENTITY_REFERENCE_NODE:
108                 return "EntityReference";
109             case Node.ENTITY_NODE:
110                 return "Entity";
111             case Node.PROCESSING_INSTRUCTION_NODE:
112                 return "ProcessingInstruction";
113             case Node.COMMENT_NODE:
114                 return "Comment";
115             case Node.DOCUMENT_NODE:
116                 return "Document";
117             case Node.DOCUMENT_TYPE_NODE:
118                 return "DocumentType";
119             case Node.DOCUMENT_FRAGMENT_NODE:
120                 return "DocumentFragment";
121             case Node.NOTATION_NODE:
122                 return "Notation";
123             default:
124         }
125         return "Unknown node type: " + type;
126     }
127 
128     private static class ElementIterator
129         implements Iterator<Element>
130     {
131         private final NodeList nodeList;
132 
133         private final String tagName;
134 
135         private int index;
136 
137         private Element next;
138 
139         public ElementIterator( NodeList nodeList, String tagName )
140         {
141             this.nodeList = nodeList;
142             this.tagName = tagName;
143             findNext();
144         }
145 
146         public boolean hasNext()
147         {
148             return ( next != null );
149         }
150 
151         private void findNext()
152         {
153             while ( index < nodeList.getLength() )
154             {
155                 Node node = nodeList.item( index );
156                 index++;
157                 if ( ( node.getNodeType() == Node.ELEMENT_NODE )
158                     && ( ( tagName == null ) || node.getNodeName().equals( tagName ) ) )
159                 {
160                     // next element found
161                     next = (Element) node;
162                     return;
163                 }
164             }
165             // no element available any more
166             next = null;
167         }
168 
169         public Element next()
170         {
171             if ( next == null )
172             {
173                 throw new NoSuchElementException();
174             }
175             Element returnValue = next;
176             findNext();
177             return returnValue;
178         }
179 
180         public void remove()
181         {
182             throw new UnsupportedOperationException();
183         }
184     }
185 }