KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > commons > xml > XMLUtils


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19
20 package org.openharmonise.commons.xml;
21
22 import org.w3c.dom.*;
23 import org.xml.sax.*;
24 import org.xml.sax.InputSource JavaDoc;
25
26 import java.io.*;
27 import java.util.*;
28 import java.util.List JavaDoc;
29 import java.util.logging.*;
30 import java.util.logging.Level JavaDoc;
31
32 import javax.xml.parsers.*;
33 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
34
35 /**
36  * Class containing utility methods for processing XML Documents.
37  *
38  * @author Matthew Large
39  * @version $Revision: 1.2 $
40  *
41  */

42
43 public class XMLUtils {
44     
45     private static final Logger m_logger = Logger.getLogger(XMLUtils.class.getName());
46     
47     
48     /**
49      * Returns the element name for the specifed <code>Element</code>, i.e.
50      * the local name in the case of namespaced element and the tag name
51      * in the case of a non-namespaced element.
52      *
53      * @param el the element
54      * @return the name of the specified element
55      */

56     public static String JavaDoc getElementName(Element el) {
57         String JavaDoc sElName = el.getLocalName();
58         
59         if(sElName == null) {
60             sElName = el.getTagName();
61         }
62         
63         return sElName;
64     }
65     
66     /**
67      * Returns the string value of the text node directly beneath an element.
68      *
69      * @param el Element from which to get the text value
70      * @return The text value from this element
71      */

72     static public String JavaDoc getChildTextValue(Element el) {
73         String JavaDoc sVal = null;
74         
75         if(el != null) {
76             Node node = el.getFirstChild();
77             
78             if(node instanceof Text) {
79                 sVal = node.getNodeValue();
80             }
81         }
82         
83         return sVal;
84     }
85
86     /**
87      * Method to get the first child matching a given name. Useful as the
88      * DOM getElementsByTagName uses the descendent axis rather than the child
89      * axis.
90      *
91      * @param el Element to check for child
92      * @param sName Name of child to check for
93      * @return First child element matching the given name, or null if not found
94      */

95     public static Element getFirstNamedChild(Element el, String JavaDoc sName) {
96         return (Element) XMLUtils.getFirstNamedChild((Node) el, sName);
97     }
98
99     /**
100      * Method to get the first child matching a given name. Useful as the
101      * DOM getElementsByTagName uses the descendent axis rather than the child
102      * axis.
103      *
104      * @param node Node to check for child
105      * @param sName Name of child to check for
106      * @return First child node matching the given name, or null if not found
107      */

108     public static Node getFirstNamedChild(Node node, String JavaDoc sName) {
109         Node retn = null;
110         String JavaDoc sElName = sName;
111         int nIndex = sName.indexOf(":");
112         if (nIndex > -1) {
113             sElName = sName.substring(nIndex + 1);
114         }
115
116         NodeList nl = node.getChildNodes();
117         for (int i = 0; i < nl.getLength() && retn == null; i++) {
118             Node currNode = nl.item(i);
119             if (currNode instanceof Element) {
120                 String JavaDoc sNodeName = getElementName((Element) currNode);
121                 
122                 if (sNodeName.equals(sElName)) {
123                     retn = currNode;
124                 }
125             }
126         }
127
128         return retn;
129     }
130
131     /**
132      * Method to get the first child element, useful as the DOM getFirstChild
133      * method is not restricted to Element nodes.
134      *
135      * @param el Element to get child from
136      * @return First child element, or null if not found
137      */

138     public static Element getFirstElementChild(Element el) {
139         Element elRetn = null;
140
141         NodeList nl = el.getChildNodes();
142         for (int i = 0; i < nl.getLength(); i++) {
143             if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) {
144                 elRetn = (Element) nl.item(i);
145                 break;
146             }
147         }
148
149         return elRetn;
150     }
151
152     /**
153      * Properly encodes entity references in a XML file in case they have
154      * been previously decoded.
155      *
156      * @param file File to fix
157      * @return Fixed file
158      */

159     public static File fixXMLFileEntities(File file) {
160         File newFile = null;
161         BufferedWriter wBuff = null;
162         BufferedReader rBuff = null;
163         try {
164             newFile = File.createTempFile("sim-", "tmp");
165             wBuff = new BufferedWriter(new FileWriter(newFile));
166             rBuff = new BufferedReader(new FileReader(file));
167
168             while (rBuff.ready()) {
169                 String JavaDoc sLine = rBuff.readLine();
170                 if (sLine.indexOf("&") > -1) {
171                     String JavaDoc sFixed = XMLUtils.encodeXMLText(sLine);
172                     wBuff.write(sFixed);
173                 } else {
174                     wBuff.write(sLine);
175                 }
176             }
177         } catch (Exception JavaDoc e) {
178             m_logger.log(Level.WARNING, e.getMessage(), e);
179         } finally {
180             try {
181                 wBuff.close();
182                 rBuff.close();
183             } catch (Exception JavaDoc ex) {
184                 m_logger.log(Level.WARNING, ex.getMessage(), ex);
185             }
186         }
187         return newFile;
188     }
189
190     /**
191      * Properly XML encodes text, ensuring that entities are correctly
192      * encoded, e.g. & becomes &amp;amp;.
193      *
194      * @param sText Text to encode
195      * @return Encoded text
196      */

197     private static String JavaDoc encodeXMLText(String JavaDoc sText) {
198         StringBuffer JavaDoc sBuff2 = new StringBuffer JavaDoc(sText);
199         StringBuffer JavaDoc sNewBuff = new StringBuffer JavaDoc();
200
201         for (int i = 0; i < sBuff2.length(); i++) {
202             char currChar = sBuff2.charAt(i);
203             if (currChar == '&') {
204                 if (sBuff2.charAt(i + 1) != 'a') {
205                     sNewBuff.append(currChar);
206                 } else if (sBuff2.charAt(i + 2) != 'p') {
207                     sNewBuff.append(currChar);
208                 } else if (
209                     sBuff2.charAt(i + 1) == 'a'
210                         && sBuff2.charAt(i + 2) == 'm'
211                         && sBuff2.charAt(i + 3) == 'p'
212                         && sBuff2.charAt(i + 4) == ';'
213                         && sBuff2.charAt(i + 5) == 'a'
214                         && sBuff2.charAt(i + 6) == 'm'
215                         && sBuff2.charAt(i + 7) == 'p'
216                         && sBuff2.charAt(i + 8) == ';') {
217                     i = i + 8;
218                     sNewBuff.append("&amp;amp;");
219                 } else if (
220                     sBuff2.charAt(i + 1) == 'a'
221                         && sBuff2.charAt(i + 2) == 'm'
222                         && sBuff2.charAt(i + 3) == 'p'
223                         && sBuff2.charAt(i + 4) == ';') {
224                     i = i + 4;
225                     sNewBuff.append("&amp;amp;");
226                 } else {
227                     sNewBuff.append("&amp;amp;");
228                 }
229             } else {
230                 sNewBuff.append(currChar);
231             }
232         }
233
234         return sNewBuff.toString();
235     }
236
237     /**
238      * Method to get the element children matching a given name. Useful as the
239      * DOM getElementsByTagName uses the descendent axis rather than the child
240      * axis.
241      *
242      * @param propEl Element to check for children
243      * @param sName Name of child to check for
244      * @return Child matching name, or null if not found
245      */

246     public static List JavaDoc getChildrenByName(Element propEl, String JavaDoc sName) {
247         NodeList nodes = propEl.getChildNodes();
248         List JavaDoc result = new ArrayList();
249         int nIndex = sName.indexOf(":");
250         
251         if(nIndex > 0) {
252             sName = sName.substring(nIndex + 1);
253         }
254
255         for (int i = 0; i < nodes.getLength(); i++) {
256             Node tmpNode = nodes.item(i);
257             if (tmpNode.getNodeType() != Node.ELEMENT_NODE) {
258                 continue;
259             }
260
261             if (getElementName((Element) tmpNode).equals(sName)) {
262                 result.add(tmpNode);
263             }
264         }
265
266         return result;
267     }
268
269     /**
270      * Method to deep copy a node from one document to another.
271      *
272      * @param originalNode Node to copy
273      * @param parent_destination Destination document
274      * @return Copy of original node, owned by parent_destination Document
275      */

276     public static Node copyNode(Node originalNode, Document parent_destination) {
277         int i = 0;
278
279         Node returnNode = null;
280
281         if (originalNode.getNodeType() == Node.ELEMENT_NODE) {
282             Element el = parent_destination.createElement(((Element) originalNode).getTagName());
283             NamedNodeMap attribs = originalNode.getAttributes();
284
285             for (i = 0; i < attribs.getLength(); i++) {
286                 Attr nextAtt = (Attr) attribs.item(i);
287                 el.setAttribute(nextAtt.getNodeName(), nextAtt.getValue());
288             }
289
290             NodeList nodes = originalNode.getChildNodes();
291
292             for (i = 0; i < nodes.getLength(); i++) {
293                 if ((nodes.item(i).getNodeType() == Node.ELEMENT_NODE)
294                     || (nodes.item(i).getNodeType() == Node.TEXT_NODE)) {
295                     el.appendChild(copyNode(nodes.item(i),parent_destination));
296                 }
297             }
298
299             returnNode = (Node) el;
300         } else if (originalNode.getNodeType() == Node.TEXT_NODE) {
301             Text el = parent_destination.createTextNode(originalNode.getNodeValue());
302
303             returnNode = (Node) el;
304         }
305
306         return returnNode;
307     }
308
309     /**
310      * Copies all children from one element to another which may be owned by a
311      * different Document.
312      *
313      * @param parent_destination Destination element to copy children to
314      * @param parent_source Source element to copy children from
315      * @param doc_destination Destination document
316      */

317     public static void copyChildren(
318         Element parent_destination,
319         Element parent_source,
320         Document doc_destination) {
321         copyChildren(parent_destination, parent_source, doc_destination,new Vector());
322     }
323
324     /**
325      * Copies all children from one element to another which may be owned by a
326      * different Document.
327      *
328      * @param parent_destination Destination element to copy children to
329      * @param parent_source Source element to copy children from
330      * @param doc_destination Destination document
331      * @param ignoreTags Element names not to copy
332      */

333     public static void copyChildren(
334         Element parent_destination,
335         Element parent_source,
336         Document doc_destination,
337         Vector ignoreTags) {
338         // copy all caption nodes (if any exist)
339
NodeList child_nodes = parent_source.getChildNodes();
340
341         for (int k = 0; k < child_nodes.getLength(); k++) {
342             if ((child_nodes.item(k).getNodeType() == Node.ELEMENT_NODE)
343                 && ignoreTags.contains(
344                     ((Element) child_nodes.item(k)).getTagName())) {
345                 continue;
346             }
347
348             Node node = child_nodes.item(k);
349
350             if (node != null) {
351                 parent_destination.appendChild(copyNode(node,doc_destination));
352             }
353         }
354     }
355     
356     /**
357      * Returns a <code>Document</code> from the given <code>String</code>
358      *
359      * @param sVal XML document in <code>String</code> form
360      * @return
361      * @throws SAXException
362      * @throws IOException
363      * @throws ParserConfigurationException
364      */

365     public static Document getDocumentFromString(String JavaDoc sVal) throws SAXException, IOException, ParserConfigurationException {
366         DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
367         factory.setNamespaceAware(true);
368         
369         StringReader sreader = new StringReader(sVal);
370         
371         InputSource JavaDoc isource = new InputSource JavaDoc(sreader);
372         
373         return factory.newDocumentBuilder().parse(isource);
374     }
375 }
Popular Tags