KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > nava > informa > utils > XmlPathUtils


1 //
2
// Informa -- RSS Library for Java
3
// Copyright (c) 2002 by Niko Schmuck
4
//
5
// Niko Schmuck
6
// http://sourceforge.net/projects/informa
7
// mailto:niko_schmuck@users.sourceforge.net
8
//
9
// This library is free software.
10
//
11
// You may redistribute it and/or modify it under the terms of the GNU
12
// Lesser General Public License as published by the Free Software Foundation.
13
//
14
// Version 2.1 of the license should be included with this distribution in
15
// the file LICENSE. If the license is not included with this distribution,
16
// you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org',
17
// or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge,
18
// MA 02139 USA.
19
//
20
// This library is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied waranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
// Lesser General Public License for more details.
24
//
25

26 // $Id: XmlPathUtils.java,v 1.3 2003/10/18 21:28:56 mharhen Exp $
27

28 package de.nava.informa.utils;
29
30 import java.util.ArrayList JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.StringTokenizer JavaDoc;
34
35 import org.jdom.Element;
36 import org.jdom.Namespace;
37
38 /**
39  * Utility class providing methods access XML attributes and elements using
40  * a path.
41  *
42  * @author Michael Harhen
43  */

44 public class XmlPathUtils {
45
46   private XmlPathUtils() {}
47
48   private static final String JavaDoc elementDelim = "/";
49   private static final String JavaDoc prefixDelim = ":";
50
51   /**
52    * Returns the value of an element's child element reached by the given path.
53    * Traverses the DOM tree from the parent until the child is reached.
54    *
55    * @param parent the parent <code>Element</code>
56    * @param childPath a path to the root of the elements.
57    * Paths are specified as element names, separated by a "/".
58    * Namespaces are allowed. e.g. "aaa:bbb/ccc:ddd/eee".
59    *
60    * @return the value of the child. <br>If <code>parent</code> is
61    * <code>null</code>, returns <code>null</code>. If
62    * <code>childPath</code> is null, returns the value of the parent.
63    */

64   public static String JavaDoc getElementValue(final Element parent, final String JavaDoc childPath) {
65
66     if (parent == null) {
67       return null;
68     } else {
69       Element child = getLeafChild(parent, childPath);
70       return (child == null) ? null : child.getTextTrim();
71     }
72   }
73
74   /**
75    * Returns the values of the specified sub-elements of the child element
76    * reached by the given path. This is useful in cases where a child has
77    * several children. Traverses the DOM tree from the parent until the root
78    * is reached, then reads the specified elements.
79    *
80    * @param parent the parent <code>Element</code>
81    * @param childPath a path to the root of the elements.
82    * Paths are specified as element names, separated by a "/".
83    * Namespaces are allowed. e.g. "aaa:bbb/ccc:ddd/eee".
84    * @param elements An array of element names. May contain namespace specifiers.
85    *
86    * @return an array containing the value of each element.
87    * <br>If <code>parent</code> or <code>elements</code> is
88    * <code>null</code>, returns <code>null</code>. If
89    * <code>childPath</code> is null, returns the specified sub-elements
90    * of the parent.
91    */

92   public static String JavaDoc[] getElementValues(final Element parent, final String JavaDoc childPath, final String JavaDoc[] elements) {
93
94     if (parent == null) {
95       return null;
96     } else {
97       Element child = getLeafChild(parent, childPath);
98       return getElementValues(child, elements);
99     }
100   }
101
102   /**
103    * Returns the values of the specified sub-elements of the child parent element.
104    * This is useful in cases where an element has several children.
105    *
106    * @param parent the parent <code>Element</code>
107    * @param children An array of child element names. May contain namespace specifiers.
108    *
109    * @return an array containing the value of each child element.
110    * <br>If <code>parent</code> or <code>children</code>
111    * is <code>null</code>, returns <code>null</code>.
112    */

113   public static String JavaDoc[] getElementValues(final Element parent, final String JavaDoc[] children) {
114     if ((parent == null) || (children == null)) {
115       return null;
116     } else {
117       int numValues = children.length;
118       String JavaDoc[] elementValues = new String JavaDoc[numValues];
119       for (int i = 0; i < numValues; ++i) {
120         Element child = getChild(parent, children[i]);
121         elementValues[i] = (child == null) ? null : child.getTextTrim();
122       }
123       return elementValues;
124     }
125   }
126
127   /**
128    * Returns the value of the attribute of the child element reached by the
129    * given path. Traverses the DOM tree from the parent until the child is
130    * reached, then reads the given attribute.
131    *
132    * @param parent the parent <code>Element</code>
133    * @param childPath a path to the root of the elements.
134    * Paths are specified as element names, separated by a "/".
135    * @param attribute the attribute.
136    * May contain a namespace specifier e.g. "rdf:resource".
137    *
138    * @return the value of the attribute.
139    * <br>If <code>parent</code> or <code>attribute</code> is
140    * <code>null</code>, returns <code>null</code> .
141    * If <code>childPath</code> is null, returns the specified
142    * attribute of the parent.
143    *
144    */

145   public static String JavaDoc getAttributeValue(final Element parent, final String JavaDoc childPath, final String JavaDoc attribute) {
146
147     if ((parent == null) || (attribute == null)) {
148       return null;
149     } else {
150       Element child = getLeafChild(parent, childPath);
151       return getAttributeValue(child, attribute);
152     }
153   }
154
155   /**
156    * Returns the value of the child element reached by the given path.
157    * This is useful in cases where a child has several attributes.
158    * Traverses the DOM tree from the parent until the child is reached.
159    *
160    * @param parent the parent <code>Element</code>
161    * @param childPath a path to the root of the elements. Paths are specified
162    * as element names, separated by a "/". Namespaces are allowed.
163    * e.g. "aaa:bbb/ccc:ddd/eee".
164    * @param attributes - An array of element names. May contain namespace
165    * specifiers.
166    *
167    * @return the value of the child. <br>If <code>parent</code> or
168    * <code>attributes</code> is <code>null</code>, returns
169    * <code>null</code>. If <code>childPath</code> is null, returns
170    * the specified attributes of the parent.
171    */

172   public static String JavaDoc[] getAttributeValues(final Element parent, final String JavaDoc childPath, final String JavaDoc[] attributes) {
173
174     if ((parent == null) || (attributes == null)) {
175       return null;
176     } else {
177       Element child = getLeafChild(parent, childPath);
178       return getAttributeValues(child, attributes);
179     }
180   }
181
182   /**
183    * Returns the values of the attributes of given element.
184    * This is useful in cases where an element has several attributes.
185    *
186    * @param element the <code>Element</code>
187    * @param attributes An array of attribute names.
188    * May contain namespace specifiers.
189    *
190    * @return an array containing the values of the element's attributes.
191    * <br>If <code>element</code> or <code>attributes</code>
192    * is <code>null</code>, returns <code>null</code> .
193    */

194   public static String JavaDoc[] getAttributeValues(final Element element, final String JavaDoc[] attributes) {
195
196     if ((element == null) || (attributes == null)) {
197       return null;
198     } else {
199       int numAttributes = attributes.length;
200       String JavaDoc[] attributeValues = new String JavaDoc[numAttributes];
201       for (int i = 0; i < numAttributes; ++i) {
202         attributeValues[i] = getAttributeValue(element, attributes[i]);
203       }
204       return attributeValues;
205     }
206   }
207
208   /**
209    * Returns an <code>Element's</code> child corresponding to the given path.
210    * Traverses the DOM tree from the parent until the child is reached.
211    *
212    * @param parent the parent <code>Element</code>
213    * @param childPath a path to the root of the elements.
214    * Paths are specified as element names, separated by a "/".
215    * @return the child.
216    * <br>If <code>childPath</code> is null, return <code>parent</code>.
217    */

218   private static Element getLeafChild(final Element parent, final String JavaDoc childPath) {
219
220     if (childPath == null) return parent;
221
222     List JavaDoc elementNames = getElementNames(childPath);
223     Iterator JavaDoc iterator = elementNames.iterator();
224     Element nextChild = parent;
225
226     while (iterator.hasNext() && (nextChild != null)) {
227       String JavaDoc elementName = (String JavaDoc) iterator.next();
228       nextChild = getChild(nextChild, elementName);
229     }
230
231     return nextChild;
232   }
233
234   /**
235    * Returns an <code>Element's</code> child corresponding to the given child
236    * name.
237    *
238    * @param parent the parent <code>Element</code>
239    * @param childName the child's name.
240    * May contain a namespace specifier.
241    *
242    * @return the child.
243    */

244   private static Element getChild(final Element parent, final String JavaDoc childName) {
245
246     int prefixPos = childName.indexOf(prefixDelim);
247     if ( (prefixPos == 0) || (prefixPos >= childName.length() - 1)) {
248       return null;
249     } else {
250       if (prefixPos == -1) {
251         return parent.getChild(childName, getNamespace(parent, null));
252       } else {
253         String JavaDoc prefix = childName.substring(0, prefixPos);
254         String JavaDoc childElementName = childName.substring(prefixPos + 1);
255         return parent.getChild(childElementName, getNamespace(parent, prefix));
256       }
257     }
258   }
259
260   /**
261    * Get the value corresponding to an <code>Element</code> and an attribute.
262    *
263    * @param element the <code>Element</code>.
264    * <code>null</code> is not acceptable.
265    * @param attribute the attribute.
266    * May contain a namespace specifier e.g. "rdf:resource".
267    * <code>null</code> is not acceptable.
268    * @return the value. The value of the <code>Element's</code> attribute,
269    * or <code>null</code> if element is <code>null</code>.
270    */

271   private static String JavaDoc getAttributeValue(Element element, String JavaDoc attribute) {
272
273     if (element == null) return null;
274     int prefixPos = attribute.indexOf(prefixDelim);
275
276     if ( (prefixPos == 0) || (prefixPos >= attribute.length() - 1)) {
277       return null;
278     } else if (prefixPos == -1) { // no prefix
279
return element.getAttributeValue(attribute);
280     } else {
281       String JavaDoc prefix = attribute.substring(0, prefixPos);
282       String JavaDoc attributeName = attribute.substring(prefixPos + 1);
283       return element.getAttributeValue(attributeName, getNamespace(element, prefix));
284     }
285   }
286
287   /**
288    * Converts a path into a <code>List</code> of element names.
289    *
290    * @param childPath a path. e.g. "aaa:bbb/ccc:ddd/eee"
291    *
292    * @return a <code>List</code> of element names.
293    * e.g. "aaa:bbb", "ccc:ddd", "eee".
294    */

295   private static List JavaDoc getElementNames(final String JavaDoc childPath) {
296
297     List JavaDoc strArray = new ArrayList JavaDoc();
298     if (childPath != null) {
299       StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(childPath, elementDelim);
300       while (st.hasMoreTokens()) {
301         String JavaDoc token = st.nextToken();
302         if (token.length() > 0) {
303           strArray.add(token);
304         }
305       }
306     }
307     return strArray;
308   }
309
310   /**
311    * Returns the Namespace corresponding to an element and a prefix.
312    *
313    * @param element the element.
314    * @param prefix the prefix.
315    *
316    * @return the Namespace.
317    */

318   private static Namespace getNamespace(final Element element, final String JavaDoc prefix) {
319     Namespace namespace = (prefix == null) ? element.getNamespace("") : element.getNamespace(prefix);
320     return (namespace == null) ? Namespace.NO_NAMESPACE : namespace;
321   }
322
323 }
324
Popular Tags