KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > xml > DOMUtil


1 /*
2  * Copyright 1999-2004 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
18 /* $Id: DOMUtil.java 109760 2004-12-04 02:55:23Z antonio $ */
19
20 package org.apache.lenya.xml;
21
22 import java.io.StringReader JavaDoc;
23 import java.util.Vector JavaDoc;
24
25 import org.apache.log4j.Category;
26 import org.w3c.dom.Attr JavaDoc;
27 import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.Element JavaDoc;
29 import org.w3c.dom.Node JavaDoc;
30 import org.w3c.dom.NodeList JavaDoc;
31
32 /**
33  * This class is a utility class for miscellaneous DOM functions, similar to
34  * org.apache.cocoon.xml.dom.DOMUtil FIXME: Merge classes or extend functionality
35  */

36 public class DOMUtil {
37     static Category log = Category.getInstance(DOMUtil.class);
38
39     DOMParserFactory dpf = null;
40
41     XPointerFactory xpf = null;
42
43     /**
44      * Ctor.
45      */

46     public DOMUtil() {
47         dpf = new DOMParserFactory();
48         xpf = new XPointerFactory();
49     }
50
51     /**
52      * Main method, used to test the class.
53      * @param args The command line arguments.
54      */

55     public static void main(String JavaDoc[] args) {
56         try {
57             DOMUtil du = new DOMUtil();
58             Document JavaDoc document = du
59                     .create("<?xml version=\"1.0\"?><Artikel><Datum><Monat Name=\"Juli\"/><Tag>23</Tag></Datum><Content/></Artikel>");
60             new DOMWriter(System.out).printWithoutFormatting(document);
61             du.setElementValue(document, "/Artikel/Datum/Tag", "25");
62             du.setElementValue(document, "/Artikel/Datum/Monat", "7");
63             du.setElementValue(document, "/Artikel/Datum/Monat", "9");
64             du.setElementValue(document, "/Artikel/Datm/Mont", "13");
65             du.setAttributeValue(document, "/Artikel/Datum/Monat/@Name", "Oktober");
66             du.setAttributeValue(document, "/Artikel/Datu/Monat/@Nam", "August");
67             du.setElementValue(document, "/Artikel/Datu/Monat", "8");
68             du.addElement(document, "/Artikel/Datum/Tag", "26");
69             du.setElementValue(document, "/Artikel/Datum/Tag", "24");
70
71             new DOMWriter(System.out).printWithoutFormatting(document);
72             System.out.print("\n");
73             System.out.print("\n");
74
75             String JavaDoc[] elements = du.getAllElementValues(document, new XPath("/Artikel/Datum/Monat"));
76
77             for (int i = 0; i < elements.length; i++) {
78                 System.out.println("Elements=" + elements[i]);
79             }
80
81             System.out.print("\n");
82             System.out.println("Datum/Monat="
83                     + du.getElementValue(document.getDocumentElement(), new XPath("Datum/Monat")));
84             System.out.println("Datm="
85                     + du.getElementValue(document.getDocumentElement(), new XPath("Datm")));
86
87             System.out.println("Datum/Monat/@Name="
88                     + du.getAttributeValue(document.getDocumentElement(), new XPath(
89                             "Datum/Monat/@Name")));
90         } catch (Exception JavaDoc e) {
91             System.err.println(e);
92         }
93     }
94
95     /**
96      * Creates a DOM document from a string.
97      *
98      * @param xml The string.
99      * @return A DOM document.
100      * @throws Exception if an error occurs.
101      *
102      * @deprecated Use {@link DocumentHelper#readDocument(java.lang.String)} instead.
103      */

104     public Document JavaDoc create(String JavaDoc xml) throws Exception JavaDoc {
105         return dpf.getDocument(new StringReader JavaDoc(xml));
106     }
107
108     /**
109      * Selects an array of elements using an XPath.
110      *
111      * @param document The document.
112      * @param xpath The XPath.
113      * @return An array of elements.
114      * @throws Exception if the XPath does not return a <code>NodeList</code> consisting of elements.
115      *
116      * @deprecated Use
117      * {@link org.apache.xpath.XPathAPI#selectNodeList(org.w3c.dom.Node, java.lang.String)}
118      * instead.
119      */

120     public Element JavaDoc[] select(Document JavaDoc document, String JavaDoc xpath) throws Exception JavaDoc {
121         log.debug(".select(): " + xpath);
122
123         Vector JavaDoc nodes = xpf.select(document, "xpointer(" + xpath + ")");
124         Element JavaDoc[] elements = new Element JavaDoc[nodes.size()];
125
126         for (int i = 0; i < nodes.size(); i++) {
127             elements[i] = (Element JavaDoc) nodes.elementAt(i);
128         }
129
130         return elements;
131     }
132
133     /**
134      * <p>
135      * This method removes all child nodes from an element and inserts a text node instead.
136      * </p>
137      * <p>
138      * Caution: Child elements are removed as well!
139      * </p>
140      * @param element The element.
141      * @param text The string to insert as a text node.
142      */

143     public void replaceText(Element JavaDoc element, String JavaDoc text) {
144         NodeList JavaDoc nl = element.getChildNodes();
145
146         for (int i = nl.getLength() - 1; i >= 0; i--) {
147             element.removeChild(nl.item(i));
148         }
149
150         element.appendChild(dpf.newTextNode(element.getOwnerDocument(), text));
151     }
152
153     /**
154      * Returns the concatenation string of all text nodes which are children of an element.
155      * The XPath is resolved against the document element.
156      *
157      * @param document The document.
158      * @param xpath The XPath of the element to resolve.
159      * @return A string.
160      * @throws Exception if an error occurs.
161      *
162      * @deprecated Use {@link DocumentHelper#getSimpleElementText(org.w3c.dom.Element) instead.}
163      */

164     public String JavaDoc getElementValue(Document JavaDoc document, XPath xpath) throws Exception JavaDoc {
165         return getElementValue(document.getDocumentElement(), xpath);
166     }
167
168     /**
169      * Returns the concatenation string of all text nodes which are children of an element.
170      * The XPath is resolved against a certain element.
171      *
172      * @param element The element to resolve the XPath against.
173      * @param xpath The XPath of the element to resolve.
174      * @return A string.
175      * @throws Exception if an error occurs.
176      *
177      * @deprecated Use {@link DocumentHelper#getSimpleElementText(org.w3c.dom.Element) instead.}
178      */

179     public String JavaDoc getElementValue(Element JavaDoc element, XPath xpath) throws Exception JavaDoc {
180         String JavaDoc value = "";
181         NodeList JavaDoc nl = getElement(element, xpath).getChildNodes();
182
183         for (int i = 0; i < nl.getLength(); i++) {
184             short nodeType = nl.item(i).getNodeType();
185
186             if (nodeType == Node.TEXT_NODE) {
187                 value = value + nl.item(i).getNodeValue();
188             } else {
189                 log.warn("XPath " + xpath + " contains node types other than just TEXT_NODE");
190             }
191         }
192
193         return value;
194     }
195
196     /**
197      * Check if elements exists This method just checks the root element! TODO: Implementation is
198      * not really finished, or is it!
199      *
200      * Replacement code:
201      *
202      * <code>
203      * Node node = XPathAPI.selectSingleNode(element, xPath);
204      * if (node != null && node instanceof Element) {
205      * exists = true;
206      * }
207      * </code>
208      *
209      * @deprecated See replacement code.
210      */

211     public boolean elementExists(Element JavaDoc element, XPath xpath) throws Exception JavaDoc {
212         log.debug(xpath);
213
214         if (xpath.parts.length > 0) {
215             NodeList JavaDoc nl = element.getElementsByTagName(xpath.parts[0]);
216
217             if (nl.getLength() == 0) {
218                 return false;
219             } else if (nl.getLength() == 1) {
220                 return true;
221             }
222         }
223         return false;
224     }
225
226     /**
227      * Get element via XPath.
228      *
229      * @deprecated Use
230      * {@link org.apache.xpath.XPathAPI#selectSingleNode(org.w3c.dom.Node, java.lang.String)}
231      * instead.
232      */

233     public Element JavaDoc getElement(Element JavaDoc element, XPath xpath) throws Exception JavaDoc {
234         log.debug(xpath);
235
236         if (xpath.parts.length > 0) {
237             NodeList JavaDoc nl = element.getElementsByTagName(xpath.parts[0]);
238
239             if (nl.getLength() == 0) {
240                 throw new Exception JavaDoc("There are no elements with Name \"" + xpath.parts[0] + "\".");
241             } else if (nl.getLength() == 1) {
242                 log.debug("There is one element with Name \"" + xpath.parts[0] + "\" ("
243                         + xpath.parts.length + ").");
244
245                 if (xpath.parts.length == 1) {
246                     return (Element JavaDoc) nl.item(0);
247                 } else {
248                     String JavaDoc newXPathString = xpath.parts[1];
249
250                     for (int i = 2; i < xpath.parts.length; i++) {
251                         newXPathString = newXPathString + "/" + xpath.parts[i];
252                     }
253
254                     return getElement((Element JavaDoc) nl.item(0), new XPath(newXPathString));
255                 }
256             } else {
257                 throw new Exception JavaDoc("There are more elements than one with Name \""
258                         + xpath.parts[0] + "\".");
259             }
260         }
261
262         return null;
263     }
264
265     /**
266      * get all elements with |xpath|, xpath has to start with the root node
267      *
268      * @param document a value of type 'Document'
269      * @param xpath a value of type 'XPath'
270      *
271      * @return a value of type 'Element[]'
272      *
273      * @exception Exception if an error occurs
274      *
275      * @deprecated Use
276      * {@link org.apache.xpath.XPathAPI#selectNodeList(org.w3c.dom.Node, java.lang.String)}
277      * instead.
278      */

279     public Element JavaDoc[] getAllElements(Document JavaDoc document, XPath xpath) throws Exception JavaDoc {
280         Vector JavaDoc nodes = xpf.select(document.getDocumentElement(), "xpointer(" + xpath.toString()
281                 + ")");
282         Element JavaDoc[] elements = new Element JavaDoc[nodes.size()];
283
284         for (int i = 0; i < nodes.size(); i++) {
285             elements[i] = (Element JavaDoc) nodes.elementAt(i);
286         }
287
288         return elements;
289     }
290
291     /**
292      * get all elements values from |xpath|, xpath has to start with the root node
293      *
294      * @param document a value of type 'Document'
295      * @param xpath a value of type 'XPath'
296      *
297      * @return a value of type 'String[]'
298      *
299      * @exception Exception if an error occurs
300      */

301     public String JavaDoc[] getAllElementValues(Document JavaDoc document, XPath xpath) throws Exception JavaDoc {
302         Vector JavaDoc nodes = xpf.select(document.getDocumentElement(), "xpointer(" + xpath.toString()
303                 + ")");
304         log.debug("n elements " + nodes.size());
305
306         String JavaDoc[] values = new String JavaDoc[nodes.size()];
307
308         for (int i = 0; i < nodes.size(); i++) {
309             values[i] = getElementValue((Element JavaDoc) nodes.elementAt(i));
310         }
311
312         return values;
313     }
314
315     /**
316      * Returns the concatenation string of all text nodes which are children of an element.
317      *
318      * @param element The element.
319      * @return A string.
320      * @throws Exception if an error occurs.
321      *
322      * Replacement code:
323      *
324      * <code>
325      * Element element = (Element) XPathAPI.selectSingleNode(document, xPath);
326      * String value = DocumentHelper.getSimpleElementText(element, "...");
327      * </code>
328      *
329      * @deprecated See replacement code.
330      */

331     public String JavaDoc getElementValue(Element JavaDoc element) throws Exception JavaDoc {
332         String JavaDoc value = "";
333         NodeList JavaDoc nl = element.getChildNodes();
334
335         for (int i = 0; i < nl.getLength(); i++) {
336             short nodeType = nl.item(i).getNodeType();
337
338             if (nodeType == Node.TEXT_NODE) {
339                 value = value + nl.item(i).getNodeValue();
340             } else {
341                 log.warn("Element " + element.getNodeName()
342                         + " contains node types other than just TEXT_NODE");
343             }
344         }
345
346         return value;
347     }
348
349     /**
350      * Return the value of an attribte named e.g. "this/myelement/(at)myattribute"
351      *
352      * @param element a value of type 'Element'
353      * @param xpath a value of type 'XPath'
354      *
355      * @return a value of type 'String'
356      *
357      * Replacement code:
358      *
359      * <code>
360      * Element element = (Element) XPathAPI.selectSingleNode(document, xPath);
361      * String value = element.getAttribute("...");
362      * </code>
363      *
364      * @deprecated See replacement code.
365      */

366     public String JavaDoc getAttributeValue(Element JavaDoc element, XPath xpath) throws Exception JavaDoc {
367         Element JavaDoc el = getElement(element, new XPath(xpath.getElementName()));
368
369         return el.getAttribute(xpath.getName());
370     }
371
372     /**
373      * Describe 'setElementValue' method here.
374      *
375      * @param document a value of type 'Document'
376      * @param xpath a value of type 'String'
377      * @param value a value of type 'String'
378      *
379      * @exception Exception if an error occurs
380      *
381      * Replacement code:
382      *
383      * <code>
384      * Element element = (Element) XPathAPI.selectSingleNode(document, xPath);
385      * DocumentHelper.setSimpleElementText(element, "...");
386      * </code>
387      *
388      * @deprecated See replacement code.
389      */

390     public void setElementValue(Document JavaDoc document, String JavaDoc xpath, String JavaDoc value) throws Exception JavaDoc {
391         Element JavaDoc[] elements = select(document, xpath);
392
393         if (elements.length >= 1) {
394             if (elements.length > 1) {
395                 log.warn("There are more elements than one with XPath \"" + xpath
396                         + "\". The value of the first element will be replaced");
397             }
398
399             replaceText(elements[0], value);
400         } else {
401             XPath xp = new XPath(xpath);
402             log.warn("XPath does not exist, but will be created: " + xp);
403
404             Element JavaDoc element = (Element JavaDoc) createNode(document, xp);
405             replaceText(element, value);
406         }
407     }
408
409     /**
410      * Replacement code:
411      *
412      * <code>
413      * Element parent = (Element) XPathAPI.selectSingleNode(document, xPath);
414      * Element child = NamespaceHelper.createElement("...", "...");
415      * parent.appendChild(child);
416      * </code>
417      *
418      * @deprecated See replacement code.
419      */

420     public void addElement(Document JavaDoc document, String JavaDoc xpath, String JavaDoc value) throws Exception JavaDoc {
421         XPath xp = new XPath(xpath);
422         Node JavaDoc parent = createNode(document, xp.getParent());
423         Element JavaDoc element = dpf.newElementNode(document, xp.getName());
424         parent.appendChild(element);
425
426         if (value != null) {
427             element.appendChild(dpf.newTextNode(element.getOwnerDocument(), value));
428         }
429     }
430
431     /**
432      * Replacement code:
433      *
434      * <code>
435      * Element element = (Element) XPathAPI.selectSingleNode(document, xPath);
436      * element.setAttribute("...", "...");
437      * </code>
438      *
439      * @deprecated See replacement code.
440      */

441     public void setAttributeValue(Document JavaDoc document, String JavaDoc xpath, String JavaDoc value) throws Exception JavaDoc {
442         Vector JavaDoc nodes = xpf.select(document, "xpointer(" + xpath + ")");
443
444         if (nodes.size() >= 1) {
445             Attr JavaDoc attribute = (Attr JavaDoc) nodes.elementAt(0);
446             attribute.setValue(value);
447         } else {
448             XPath xp = new XPath(xpath);
449             log.debug("XPath does not exist, but will be created: " + xp);
450
451             Attr JavaDoc attribute = (Attr JavaDoc) createNode(document, xp);
452             attribute.setValue(value);
453         }
454     }
455
456     /**
457      * <ul>
458      * <li>If the XPath expression denotes an element, the child nodes of this element are replaced by a single
459      * text node.</li>
460      * <li>If the XPath expression denotes an attribute, the attribute value is set.</li>
461      * <li>Otherwise, an error is logged.</li>
462      * </ul>
463      *
464      * @param document The document to resolve the XPath against.
465      * @param xpath The XPath.
466      * @param value A string.
467      * @throws Exception if an error occurs.
468      */

469     public void setValue(Document JavaDoc document, XPath xpath, String JavaDoc value) throws Exception JavaDoc {
470         short type = xpath.getType();
471
472         if (type == Node.ATTRIBUTE_NODE) {
473             setAttributeValue(document, xpath.toString(), value);
474         } else if (type == Node.ELEMENT_NODE) {
475             setElementValue(document, xpath.toString(), value);
476         } else {
477             log.error("No such type: " + type);
478         }
479     }
480
481     /**
482      * Replacement code:
483      *
484      * <code>
485      * Element parent = XPathAPI.selectSingleNode(...);
486      * Element child = document.createElementNS("http://...", "...");
487      * parent.appendChild(child);
488      * </code>
489      *
490      * @deprecated See replacement code.
491      */

492     public Node JavaDoc createNode(Document JavaDoc document, XPath xpath) throws Exception JavaDoc {
493         log.debug(xpath);
494
495         Node JavaDoc node = null;
496         Vector JavaDoc nodes = xpf.select(document, "xpointer(" + xpath + ")");
497
498         if (nodes.size() >= 1) {
499             node = (Node JavaDoc) nodes.elementAt(0);
500         } else {
501             Node JavaDoc parentNode = createNode(document, xpath.getParent());
502
503             if (xpath.getType() == Node.ATTRIBUTE_NODE) {
504                 ((Element JavaDoc) parentNode).setAttribute(xpath.getNameWithoutPredicates(), "null");
505                 node = ((Element JavaDoc) parentNode).getAttributeNode(xpath.getNameWithoutPredicates());
506             } else {
507                 node = dpf.newElementNode(document, xpath.getNameWithoutPredicates());
508                 parentNode.appendChild(node);
509             }
510         }
511
512         return node;
513     }
514 }
Popular Tags