1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.model;
17
18 import org.w3c.dom.*;
19
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Map;
23 import java.util.Set;
24
25
26
27
28
29
30
31
32
33
34
35
36 public class XMLUtil {
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public static String documentToString(Document document) throws Exception {
55 return documentToString(document, true);
56 }
57
58 public static String documentToString(Document document, boolean standalone) throws Exception {
59 String prol = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"" + (standalone ? "yes" : "no") + "\"?>";
60 return prol + nodeToString(document.getDocumentElement(), new HashSet<String>(), document.getDocumentElement().getNamespaceURI());
61 }
62
63 public static String documentToFragmentString(Document document) throws Exception {
64 return nodeToString(document.getDocumentElement(), new HashSet<String>(), document.getDocumentElement().getNamespaceURI());
65 }
66
67 protected static String nodeToString(Node node, Set<String> parentPrefixes, String namespaceURI) throws Exception {
68 StringBuilder b = new StringBuilder();
69
70 if (node == null) {
71 return "";
72 }
73
74 if (node instanceof Element) {
75 Element element = (Element) node;
76 b.append("<");
77 b.append(element.getNodeName());
78
79 Map<String, String> thisLevelPrefixes = new HashMap<>();
80 if (element.getPrefix() != null && !parentPrefixes.contains(element.getPrefix())) {
81 thisLevelPrefixes.put(element.getPrefix(), element.getNamespaceURI());
82 }
83
84 if (element.hasAttributes()) {
85 NamedNodeMap map = element.getAttributes();
86 for (int i = 0; i < map.getLength(); i++) {
87 Node attr = map.item(i);
88 if (attr.getNodeName().startsWith("xmlns")) continue;
89 if (attr.getPrefix() != null && !parentPrefixes.contains(attr.getPrefix())) {
90 thisLevelPrefixes.put(attr.getPrefix(), element.getNamespaceURI());
91 }
92 b.append(" ");
93 b.append(attr.getNodeName());
94 b.append("=\"");
95 b.append(attr.getNodeValue());
96 b.append("\"");
97 }
98 }
99
100 if (namespaceURI != null && !thisLevelPrefixes.containsValue(namespaceURI) &&
101 !namespaceURI.equals(element.getParentNode().getNamespaceURI())) {
102 b.append(" xmlns=\"").append(namespaceURI).append("\"");
103 }
104
105 for (Map.Entry<String, String> entry : thisLevelPrefixes.entrySet()) {
106 b.append(" xmlns:").append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
107 parentPrefixes.add(entry.getKey());
108 }
109
110 NodeList children = element.getChildNodes();
111 boolean hasOnlyAttributes = true;
112 for (int i = 0; i < children.getLength(); i++) {
113 Node child = children.item(i);
114 if (child.getNodeType() != Node.ATTRIBUTE_NODE) {
115 hasOnlyAttributes = false;
116 break;
117 }
118 }
119 if (!hasOnlyAttributes) {
120 b.append(">");
121 for (int i = 0; i < children.getLength(); i++) {
122 b.append(nodeToString(children.item(i), parentPrefixes, children.item(i).getNamespaceURI()));
123 }
124 b.append("</");
125 b.append(element.getNodeName());
126 b.append(">");
127 } else {
128 b.append("/>");
129 }
130
131 for (String thisLevelPrefix : thisLevelPrefixes.keySet()) {
132 parentPrefixes.remove(thisLevelPrefix);
133 }
134
135 } else if (node.getNodeValue() != null) {
136 b.append(encodeText(node.getNodeValue(), node instanceof Attr));
137 }
138
139 return b.toString();
140 }
141
142 public static String encodeText(String s) {
143 return encodeText(s, true);
144 }
145
146 public static String encodeText(String s, boolean encodeQuotes) {
147 s = s.replaceAll("&", "&");
148 s = s.replaceAll("<", "<");
149 s = s.replaceAll(">", ">");
150 if(encodeQuotes) {
151 s = s.replaceAll("'", "'");
152 s = s.replaceAll("\"", """);
153 }
154 return s;
155 }
156
157 public static Element appendNewElement(Document document, Element parent, Enum el) {
158 return appendNewElement(document, parent, el.toString());
159 }
160
161 public static Element appendNewElement(Document document, Element parent, String element) {
162 Element child = document.createElement(element);
163 parent.appendChild(child);
164 return child;
165 }
166
167 public static Element appendNewElementIfNotNull(Document document, Element parent, Enum el, Object content) {
168 return appendNewElementIfNotNull(document, parent, el, content, null);
169 }
170
171 public static Element appendNewElementIfNotNull(Document document, Element parent, Enum el, Object content, String namespace) {
172 return appendNewElementIfNotNull(document, parent, el.toString(), content, namespace);
173 }
174
175 public static Element appendNewElementIfNotNull(Document document, Element parent, String element, Object content) {
176 return appendNewElementIfNotNull(document, parent, element, content, null);
177 }
178
179 public static Element appendNewElementIfNotNull(Document document, Element parent, String element, Object content, String namespace) {
180 if (content == null) return parent;
181 return appendNewElement(document, parent, element, content, namespace);
182 }
183
184 public static Element appendNewElement(Document document, Element parent, String element, Object content) {
185 return appendNewElement(document, parent, element, content, null);
186 }
187
188 public static Element appendNewElement(Document document, Element parent, String element, Object content, String namespace) {
189 Element childElement;
190 if (namespace != null) {
191 childElement = document.createElementNS(namespace, element);
192 } else {
193 childElement = document.createElement(element);
194 }
195
196 if (content != null) {
197
198
199
200 childElement.appendChild(document.createTextNode(content.toString()));
201 }
202
203 parent.appendChild(childElement);
204 return childElement;
205 }
206
207
208 public static String getTextContent(Node node) {
209 StringBuffer buffer = new StringBuffer();
210 NodeList childList = node.getChildNodes();
211 for (int i = 0; i < childList.getLength(); i++) {
212 Node child = childList.item(i);
213 if (child.getNodeType() != Node.TEXT_NODE)
214 continue;
215 buffer.append(child.getNodeValue());
216 }
217 return buffer.toString();
218 }
219
220 }