View Javadoc

1   /*
2    * Copyright 2004,2007 The Apache Software Foundation.
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  package org.apache.ws.commons.schema.utils;
18  
19  import org.w3c.dom.*;
20  
21  /**
22   * Some useful utility methods.
23   * This class was modified in Xerces2 with a view to abstracting as
24   * much as possible away from the representation of the underlying
25   * parsed structure (i.e., the DOM).  This was done so that, if Xerces
26   * ever adopts an in-memory representation more efficient than the DOM
27   * (such as a DTM), we should easily be able to convert our schema
28   * parsing to utilize it.
29   *
30   * @version $ID DOMUtil
31   */
32  public class DOMUtil {
33  
34      //
35      // Constructors
36      //
37  
38      /**
39       * This class cannot be instantiated.
40       */
41      protected DOMUtil() {
42      }
43  
44      //
45      // Public static methods
46      //
47  
48      /**
49       * Finds and returns the first child element node.
50       */
51      public static Element getFirstChildElement(Node parent) {
52  
53          // search for node
54          Node child = parent.getFirstChild();
55          while (child != null) {
56              if (child.getNodeType() == Node.ELEMENT_NODE) {
57                  return (Element) child;
58              }
59              child = child.getNextSibling();
60          }
61  
62          // not found
63          return null;
64  
65      } // getFirstChildElement(Node):Element
66  
67      /**
68       * Finds and returns the last child element node.
69       */
70      public static Element getLastChildElement(Node parent) {
71  
72          // search for node
73          Node child = parent.getLastChild();
74          while (child != null) {
75              if (child.getNodeType() == Node.ELEMENT_NODE) {
76                  return (Element) child;
77              }
78              child = child.getPreviousSibling();
79          }
80  
81          // not found
82          return null;
83  
84      } // getLastChildElement(Node):Element
85  
86  
87      /**
88       * Finds and returns the next sibling element node.
89       */
90      public static Element getNextSiblingElement(Node node) {
91  
92          // search for node
93          Node sibling = node.getNextSibling();
94          while (sibling != null) {
95              if (sibling.getNodeType() == Node.ELEMENT_NODE) {
96                  return (Element) sibling;
97              }
98              sibling = sibling.getNextSibling();
99          }
100 
101         // not found
102         return null;
103 
104     } // getNextSiblingElement(Node):Element
105 
106     /**
107      * Finds and returns the first child node with the given name.
108      */
109     public static Element getFirstChildElement(Node parent, String elemName) {
110 
111         // search for node
112         Node child = parent.getFirstChild();
113         while (child != null) {
114             if (child.getNodeType() == Node.ELEMENT_NODE) {
115                 if (child.getNodeName().equals(elemName)) {
116                     return (Element) child;
117                 }
118             }
119             child = child.getNextSibling();
120         }
121 
122         // not found
123         return null;
124 
125     } // getFirstChildElement(Node,String):Element
126 
127     /**
128      * Finds and returns the last child node with the given name.
129      */
130     public static Element getLastChildElement(Node parent, String elemName) {
131 
132         // search for node
133         Node child = parent.getLastChild();
134         while (child != null) {
135             if (child.getNodeType() == Node.ELEMENT_NODE) {
136                 if (child.getNodeName().equals(elemName)) {
137                     return (Element) child;
138                 }
139             }
140             child = child.getPreviousSibling();
141         }
142 
143         // not found
144         return null;
145 
146     } // getLastChildElement(Node,String):Element
147 
148     /**
149      * Finds and returns the next sibling node with the given name.
150      */
151     public static Element getNextSiblingElement(Node node, String elemName) {
152 
153         // search for node
154         Node sibling = node.getNextSibling();
155         while (sibling != null) {
156             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
157                 if (sibling.getNodeName().equals(elemName)) {
158                     return (Element) sibling;
159                 }
160             }
161             sibling = sibling.getNextSibling();
162         }
163 
164         // not found
165         return null;
166 
167     } // getNextSiblingdElement(Node,String):Element
168 
169     /**
170      * Finds and returns the first child node with the given qualified name.
171      */
172     public static Element getFirstChildElementNS(Node parent,
173                                                  String uri, String localpart) {
174 
175         // search for node
176         Node child = parent.getFirstChild();
177         while (child != null) {
178             if (child.getNodeType() == Node.ELEMENT_NODE) {
179                 String childURI = child.getNamespaceURI();
180                 if (childURI != null && childURI.equals(uri) &&
181                         child.getLocalName().equals(localpart)) {
182                     return (Element) child;
183                 }
184             }
185             child = child.getNextSibling();
186         }
187 
188         // not found
189         return null;
190 
191     } // getFirstChildElementNS(Node,String,String):Element
192 
193     /**
194      * Finds and returns the last child node with the given qualified name.
195      */
196     public static Element getLastChildElementNS(Node parent,
197                                                 String uri, String localpart) {
198 
199         // search for node
200         Node child = parent.getLastChild();
201         while (child != null) {
202             if (child.getNodeType() == Node.ELEMENT_NODE) {
203                 String childURI = child.getNamespaceURI();
204                 if (childURI != null && childURI.equals(uri) &&
205                         child.getLocalName().equals(localpart)) {
206                     return (Element) child;
207                 }
208             }
209             child = child.getPreviousSibling();
210         }
211 
212         // not found
213         return null;
214 
215     } // getLastChildElementNS(Node,String,String):Element
216 
217     /**
218      * Finds and returns the next sibling node with the given qualified name.
219      */
220     public static Element getNextSiblingElementNS(Node node,
221                                                   String uri, String localpart) {
222 
223         // search for node
224         Node sibling = node.getNextSibling();
225         while (sibling != null) {
226             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
227                 String siblingURI = sibling.getNamespaceURI();
228                 if (siblingURI != null && siblingURI.equals(uri) &&
229                         sibling.getLocalName().equals(localpart)) {
230                     return (Element) sibling;
231                 }
232             }
233             sibling = sibling.getNextSibling();
234         }
235 
236         // not found
237         return null;
238 
239     } // getNextSiblingdElementNS(Node,String,String):Element
240 
241     /**
242      * Finds and returns the first child node with the given name.
243      */
244     public static Element getFirstChildElement(Node parent, String elemNames[]) {
245 
246         // search for node
247         Node child = parent.getFirstChild();
248         while (child != null) {
249             if (child.getNodeType() == Node.ELEMENT_NODE) {
250                 for (int i = 0; i < elemNames.length; i++) {
251                     if (child.getNodeName().equals(elemNames[i])) {
252                         return (Element) child;
253                     }
254                 }
255             }
256             child = child.getNextSibling();
257         }
258 
259         // not found
260         return null;
261 
262     } // getFirstChildElement(Node,String[]):Element
263 
264     /**
265      * Finds and returns the last child node with the given name.
266      */
267     public static Element getLastChildElement(Node parent, String elemNames[]) {
268 
269         // search for node
270         Node child = parent.getLastChild();
271         while (child != null) {
272             if (child.getNodeType() == Node.ELEMENT_NODE) {
273                 for (int i = 0; i < elemNames.length; i++) {
274                     if (child.getNodeName().equals(elemNames[i])) {
275                         return (Element) child;
276                     }
277                 }
278             }
279             child = child.getPreviousSibling();
280         }
281 
282         // not found
283         return null;
284 
285     } // getLastChildElement(Node,String[]):Element
286 
287     /**
288      * Finds and returns the next sibling node with the given name.
289      */
290     public static Element getNextSiblingElement(Node node, String elemNames[]) {
291 
292         // search for node
293         Node sibling = node.getNextSibling();
294         while (sibling != null) {
295             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
296                 for (int i = 0; i < elemNames.length; i++) {
297                     if (sibling.getNodeName().equals(elemNames[i])) {
298                         return (Element) sibling;
299                     }
300                 }
301             }
302             sibling = sibling.getNextSibling();
303         }
304 
305         // not found
306         return null;
307 
308     } // getNextSiblingdElement(Node,String[]):Element
309 
310     /**
311      * Finds and returns the first child node with the given qualified name.
312      */
313     public static Element getFirstChildElementNS(Node parent,
314                                                  String[][] elemNames) {
315 
316         // search for node
317         Node child = parent.getFirstChild();
318         while (child != null) {
319             if (child.getNodeType() == Node.ELEMENT_NODE) {
320                 for (int i = 0; i < elemNames.length; i++) {
321                     String uri = child.getNamespaceURI();
322                     if (uri != null && uri.equals(elemNames[i][0]) &&
323                             child.getLocalName().equals(elemNames[i][1])) {
324                         return (Element) child;
325                     }
326                 }
327             }
328             child = child.getNextSibling();
329         }
330 
331         // not found
332         return null;
333 
334     } // getFirstChildElementNS(Node,String[][]):Element
335 
336     /**
337      * Finds and returns the last child node with the given qualified name.
338      */
339     public static Element getLastChildElementNS(Node parent,
340                                                 String[][] elemNames) {
341 
342         // search for node
343         Node child = parent.getLastChild();
344         while (child != null) {
345             if (child.getNodeType() == Node.ELEMENT_NODE) {
346                 for (int i = 0; i < elemNames.length; i++) {
347                     String uri = child.getNamespaceURI();
348                     if (uri != null && uri.equals(elemNames[i][0]) &&
349                             child.getLocalName().equals(elemNames[i][1])) {
350                         return (Element) child;
351                     }
352                 }
353             }
354             child = child.getPreviousSibling();
355         }
356 
357         // not found
358         return null;
359 
360     } // getLastChildElementNS(Node,String[][]):Element
361 
362     /**
363      * Finds and returns the next sibling node with the given qualified name.
364      */
365     public static Element getNextSiblingElementNS(Node node,
366                                                   String[][] elemNames) {
367 
368         // search for node
369         Node sibling = node.getNextSibling();
370         while (sibling != null) {
371             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
372                 for (int i = 0; i < elemNames.length; i++) {
373                     String uri = sibling.getNamespaceURI();
374                     if (uri != null && uri.equals(elemNames[i][0]) &&
375                             sibling.getLocalName().equals(elemNames[i][1])) {
376                         return (Element) sibling;
377                     }
378                 }
379             }
380             sibling = sibling.getNextSibling();
381         }
382 
383         // not found
384         return null;
385 
386     } // getNextSiblingdElementNS(Node,String[][]):Element
387 
388     /**
389      * Finds and returns the first child node with the given name and
390      * attribute name, value pair.
391      */
392     public static Element getFirstChildElement(Node parent,
393                                                String elemName,
394                                                String attrName,
395                                                String attrValue) {
396 
397         // search for node
398         Node child = parent.getFirstChild();
399         while (child != null) {
400             if (child.getNodeType() == Node.ELEMENT_NODE) {
401                 Element element = (Element) child;
402                 if (element.getNodeName().equals(elemName) &&
403                         element.getAttribute(attrName).equals(attrValue)) {
404                     return element;
405                 }
406             }
407             child = child.getNextSibling();
408         }
409 
410         // not found
411         return null;
412 
413     } // getFirstChildElement(Node,String,String,String):Element
414 
415     /**
416      * Finds and returns the last child node with the given name and
417      * attribute name, value pair.
418      */
419     public static Element getLastChildElement(Node parent,
420                                               String elemName,
421                                               String attrName,
422                                               String attrValue) {
423 
424         // search for node
425         Node child = parent.getLastChild();
426         while (child != null) {
427             if (child.getNodeType() == Node.ELEMENT_NODE) {
428                 Element element = (Element) child;
429                 if (element.getNodeName().equals(elemName) &&
430                         element.getAttribute(attrName).equals(attrValue)) {
431                     return element;
432                 }
433             }
434             child = child.getPreviousSibling();
435         }
436 
437         // not found
438         return null;
439 
440     } // getLastChildElement(Node,String,String,String):Element
441 
442     /**
443      * Finds and returns the next sibling node with the given name and
444      * attribute name, value pair. Since only elements have attributes,
445      * the node returned will be of type Node.ELEMENT_NODE.
446      */
447     public static Element getNextSiblingElement(Node node,
448                                                 String elemName,
449                                                 String attrName,
450                                                 String attrValue) {
451 
452         // search for node
453         Node sibling = node.getNextSibling();
454         while (sibling != null) {
455             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
456                 Element element = (Element) sibling;
457                 if (element.getNodeName().equals(elemName) &&
458                         element.getAttribute(attrName).equals(attrValue)) {
459                     return element;
460                 }
461             }
462             sibling = sibling.getNextSibling();
463         }
464 
465         // not found
466         return null;
467 
468     } // getNextSiblingElement(Node,String,String,String):Element
469 
470     /**
471      * Returns the concatenated child text of the specified node.
472      * This method only looks at the immediate children of type
473      * <code>Node.TEXT_NODE</code> or the children of any child
474      * node that is of type <code>Node.CDATA_SECTION_NODE</code>
475      * for the concatenation.
476      *
477      * @param node The node to look at.
478      */
479     public static String getChildText(Node node) {
480 
481         // is there anything to do?
482         if (node == null) {
483             return null;
484         }
485 
486         // concatenate children text
487         StringBuffer str = new StringBuffer();
488         Node child = node.getFirstChild();
489         while (child != null) {
490             short type = child.getNodeType();
491             if (type == Node.TEXT_NODE) {
492                 str.append(child.getNodeValue());
493             } else if (type == Node.CDATA_SECTION_NODE) {
494                 str.append(getChildText(child));
495             }
496             child = child.getNextSibling();
497         }
498 
499         // return text value
500         return str.toString();
501 
502     } // getChildText(Node):String
503 
504     // return the name of this element
505     public static String getName(Node node) {
506         return node.getNodeName();
507     } // getLocalName(Element):  String
508 
509     /**
510      * returns local name of this element if not null, otherwise
511      * returns the name of the node
512      */
513     public static String getLocalName(Node node) {
514         String name = node.getLocalName();
515         return (name != null) ? name : node.getNodeName();
516     } // getLocalName(Element):  String
517 
518     public static Element getParent(Element elem) {
519         Node parent = elem.getParentNode();
520         if (parent instanceof Element)
521             return (Element) parent;
522         return null;
523     } // getParent(Element):Element
524 
525     // get the Document of which this Node is a part
526     public static Document getDocument(Node node) {
527         return node.getOwnerDocument();
528     } // getDocument(Node):Document
529 
530     // return this Document's root node
531     public static Element getRoot(Document doc) {
532         return doc.getDocumentElement();
533     } // getRoot(Document(:  Element
534 
535     // some methods for handling attributes:
536 
537     // return the right attribute node
538     public static Attr getAttr(Element elem, String name) {
539         return elem.getAttributeNode(name);
540     } // getAttr(Element, String):Attr
541 
542     // return the right attribute node
543     public static Attr getAttrNS(Element elem, String nsUri,
544                                  String localName) {
545         return elem.getAttributeNodeNS(nsUri, localName);
546     } // getAttrNS(Element, String):Attr
547 
548     // get all the attributes for an Element
549     public static Attr[] getAttrs(Element elem) {
550         NamedNodeMap attrMap = elem.getAttributes();
551         Attr[] attrArray = new Attr[attrMap.getLength()];
552         for (int i = 0; i < attrMap.getLength(); i++)
553             attrArray[i] = (Attr) attrMap.item(i);
554         return attrArray;
555     } // getAttrs(Element):  Attr[]
556 
557     // get attribute's value
558     public static String getValue(Attr attribute) {
559         return attribute.getValue();
560     } // getValue(Attr):String
561 
562     // It is noteworthy that, because of the way the DOM specs
563     // work, the next two methods return the empty string (not
564     // null!) when the attribute with the specified name does not
565     // exist on an element.  Beware!
566 
567     // return the value of the attribute of the given element
568     // with the given name
569     public static String getAttrValue(Element elem, String name) {
570         return elem.getAttribute(name);
571     } // getAttr(Element, String):Attr
572 
573     // return the value of the attribute of the given element
574     // with the given name
575     public static String getAttrValueNS(Element elem, String nsUri,
576                                         String localName) {
577         return elem.getAttributeNS(nsUri, localName);
578     } // getAttrValueNS(Element, String):Attr
579 
580     // return the namespace URI
581     public static String getNamespaceURI(Node node) {
582         return node.getNamespaceURI();
583     }
584 } // class XUtil