1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codehaus.xfire.util;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.io.StringReader;
22
23 import javax.xml.parsers.DocumentBuilder;
24 import javax.xml.parsers.DocumentBuilderFactory;
25 import javax.xml.parsers.ParserConfigurationException;
26 import javax.xml.transform.OutputKeys;
27 import javax.xml.transform.Transformer;
28 import javax.xml.transform.TransformerException;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.dom.DOMSource;
31 import javax.xml.transform.stream.StreamResult;
32
33 import org.w3c.dom.Document;
34 import org.w3c.dom.NamedNodeMap;
35 import org.w3c.dom.Node;
36 import org.xml.sax.EntityResolver;
37 import org.xml.sax.InputSource;
38 import org.xml.sax.SAXException;
39
40 /***
41 * Few simple utils to read DOM. This is originally from the Jakarta Commons
42 * Modeler.
43 *
44 * @author Costin Manolache
45 */
46 public class DOMUtils
47 {
48 /***
49 * Get the trimed text content of a node or null if there is no text
50 */
51 public static String getContent(Node n)
52 {
53 if (n == null)
54 return null;
55 Node n1 = DOMUtils.getChild(n, Node.TEXT_NODE);
56
57 if (n1 == null)
58 return null;
59
60 String s1 = n1.getNodeValue();
61 return s1.trim();
62 }
63
64 /***
65 * Get the first element child.
66 *
67 * @param parent
68 * lookup direct childs
69 * @param name
70 * name of the element. If null return the first element.
71 */
72 public static Node getChild(Node parent, String name)
73 {
74 if (parent == null)
75 return null;
76 Node first = parent.getFirstChild();
77 if (first == null)
78 return null;
79
80 for (Node node = first; node != null; node = node.getNextSibling())
81 {
82
83
84 if (node.getNodeType() != Node.ELEMENT_NODE)
85 continue;
86 if (name != null && name.equals(node.getNodeName()))
87 {
88 return node;
89 }
90 if (name == null)
91 {
92 return node;
93 }
94 }
95 return null;
96 }
97
98 public static String getAttribute(Node element, String attName)
99 {
100 NamedNodeMap attrs = element.getAttributes();
101 if (attrs == null)
102 return null;
103 Node attN = attrs.getNamedItem(attName);
104 if (attN == null)
105 return null;
106 return attN.getNodeValue();
107 }
108
109 public static void setAttribute(Node node, String attName, String val)
110 {
111 NamedNodeMap attributes = node.getAttributes();
112 Node attNode = node.getOwnerDocument().createAttribute(attName);
113 attNode.setNodeValue(val);
114 attributes.setNamedItem(attNode);
115 }
116
117 public static void removeAttribute(Node node, String attName)
118 {
119 NamedNodeMap attributes = node.getAttributes();
120 attributes.removeNamedItem(attName);
121 }
122
123 /***
124 * Set or replace the text value
125 */
126 public static void setText(Node node, String val)
127 {
128 Node chld = DOMUtils.getChild(node, Node.TEXT_NODE);
129 if (chld == null)
130 {
131 Node textN = node.getOwnerDocument().createTextNode(val);
132 node.appendChild(textN);
133 return;
134 }
135
136 chld.setNodeValue(val);
137 }
138
139 /***
140 * Find the first direct child with a given attribute.
141 *
142 * @param parent
143 * @param elemName
144 * name of the element, or null for any
145 * @param attName
146 * attribute we're looking for
147 * @param attVal
148 * attribute value or null if we just want any
149 */
150 public static Node findChildWithAtt(Node parent, String elemName,
151 String attName, String attVal)
152 {
153
154 Node child = DOMUtils.getChild(parent, Node.ELEMENT_NODE);
155 if (attVal == null)
156 {
157 while (child != null
158 && (elemName == null || elemName
159 .equals(child.getNodeName()))
160 && DOMUtils.getAttribute(child, attName) != null)
161 {
162 child = getNext(child, elemName, Node.ELEMENT_NODE);
163 }
164 }
165 else
166 {
167 while (child != null
168 && (elemName == null || elemName
169 .equals(child.getNodeName()))
170 && !attVal.equals(DOMUtils.getAttribute(child, attName)))
171 {
172 child = getNext(child, elemName, Node.ELEMENT_NODE);
173 }
174 }
175 return child;
176 }
177
178 /***
179 * Get the first child's content ( ie it's included TEXT node ).
180 */
181 public static String getChildContent(Node parent, String name)
182 {
183 Node first = parent.getFirstChild();
184 if (first == null)
185 return null;
186 for (Node node = first; node != null; node = node.getNextSibling())
187 {
188
189
190 if (name.equals(node.getNodeName()))
191 {
192 return getContent(node);
193 }
194 }
195 return null;
196 }
197
198 /***
199 * Get the first direct child with a given type
200 */
201 public static Node getChild(Node parent, int type)
202 {
203 Node n = parent.getFirstChild();
204 while (n != null && type != n.getNodeType())
205 {
206 n = n.getNextSibling();
207 }
208 if (n == null)
209 return null;
210 return n;
211 }
212
213 /***
214 * Get the next sibling with the same name and type
215 */
216 public static Node getNext(Node current)
217 {
218 String name = current.getNodeName();
219 int type = current.getNodeType();
220 return getNext(current, name, type);
221 }
222
223 /***
224 * Return the next sibling with a given name and type
225 */
226 public static Node getNext(Node current, String name, int type)
227 {
228 Node first = current.getNextSibling();
229 if (first == null)
230 return null;
231
232 for (Node node = first; node != null; node = node.getNextSibling())
233 {
234
235 if (type >= 0 && node.getNodeType() != type)
236 continue;
237
238
239 if (name == null)
240 return node;
241 if (name.equals(node.getNodeName()))
242 {
243 return node;
244 }
245 }
246 return null;
247 }
248
249 public static class NullResolver implements EntityResolver
250 {
251 public InputSource resolveEntity(String publicId, String systemId)
252 throws SAXException, IOException
253 {
254 return new InputSource(new StringReader(""));
255 }
256 }
257
258 /***
259 * Read XML as DOM.
260 */
261 public static Document readXml(InputStream is) throws SAXException,
262 IOException, ParserConfigurationException
263 {
264 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
265
266 dbf.setValidating(false);
267 dbf.setIgnoringComments(false);
268 dbf.setIgnoringElementContentWhitespace(true);
269
270
271
272 DocumentBuilder db = null;
273 db = dbf.newDocumentBuilder();
274 db.setEntityResolver(new NullResolver());
275
276
277
278 Document doc = db.parse(is);
279 return doc;
280 }
281
282 public static void writeXml(Node n, OutputStream os)
283 throws TransformerException
284 {
285 TransformerFactory tf = TransformerFactory.newInstance();
286
287 Transformer t = tf.newTransformer();
288 t.setOutputProperty(OutputKeys.INDENT, "yes");
289 t.transform(new DOMSource(n), new StreamResult(os));
290 }
291 }