1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.xml;
17
18 import java.io.StringReader;
19 import java.util.Iterator;
20 import java.util.Stack;
21
22 import javax.xml.stream.XMLEventReader;
23 import javax.xml.stream.XMLInputFactory;
24 import javax.xml.stream.XMLStreamException;
25 import javax.xml.stream.events.Attribute;
26 import javax.xml.stream.events.Characters;
27 import javax.xml.stream.events.StartElement;
28 import javax.xml.stream.events.XMLEvent;
29
30 import org.apache.commons.lang.StringUtils;
31 import org.w3c.dom.Document;
32 import org.w3c.dom.Element;
33 import org.w3c.dom.Text;
34
35
36
37
38
39
40
41 public class DomCopyReader
42 {
43
44
45
46
47
48
49
50
51
52
53 private static final String ARTIFICIAL_GI = "root";
54
55
56
57
58
59
60 private static final String ARTIFICIAL_START_TAG = '<' + ARTIFICIAL_GI + '>';
61
62
63
64
65
66
67 private static final String ARTIFICIAL_END_TAG = "</" + ARTIFICIAL_GI + '>';
68
69
70
71
72
73
74 private final Document document;
75
76
77
78
79 private final Stack<Element> elements = new Stack<Element>();
80
81
82
83
84
85
86
87
88
89
90
91 public DomCopyReader(final Document document, final Element element)
92 {
93 this.document = document;
94 elements.push(element);
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 public void copy(final String xmlFragment) throws XMLStreamException
114 {
115 final XMLInputFactory factory = XMLInputFactory.newInstance();
116 final boolean isFragment = isFragment(xmlFragment);
117 final XMLEventReader eventReader;
118 if (isFragment)
119 {
120 eventReader =
121 factory.createXMLEventReader(new StringReader(ARTIFICIAL_START_TAG
122 + xmlFragment
123 + ARTIFICIAL_END_TAG));
124 boolean run = true;
125 while (run && eventReader.hasNext())
126 {
127 final XMLEvent event = eventReader.nextEvent();
128 if (event.getEventType() == XMLEvent.START_ELEMENT)
129 {
130 run = false;
131 }
132 }
133 }
134 else
135 {
136 eventReader = factory.createXMLEventReader(new StringReader(xmlFragment));
137 }
138 parse(eventReader);
139 }
140
141
142
143
144
145
146
147
148 private static boolean isFragment(final String xmlFragment)
149 {
150 return xmlFragment.charAt(0) != '<';
151 }
152
153
154
155
156
157
158
159 private void parse(final XMLEventReader eventReader)
160 throws XMLStreamException
161 {
162 int level = 0;
163 while (eventReader.hasNext())
164 {
165 final XMLEvent event = eventReader.nextEvent();
166 switch (event.getEventType())
167 {
168 case XMLEvent.START_ELEMENT:
169 level++;
170 handleStartElement(event);
171 break;
172 case XMLEvent.END_ELEMENT:
173 level--;
174 if (level >= 0)
175 {
176 elements.pop();
177 }
178 break;
179 case XMLEvent.CHARACTERS:
180 final Characters chars = event.asCharacters();
181 final String content = chars.getData();
182 final Text text = document.createTextNode(content);
183 elements.peek().appendChild(text);
184 default:
185
186 break;
187 }
188 }
189 }
190
191
192
193
194
195
196
197 @SuppressWarnings("unchecked")
198 private void handleStartElement(final XMLEvent event)
199 throws XMLStreamException
200 {
201 final StartElement element = event.asStartElement();
202 final String gi = element.getName().getLocalPart();
203 final String prefix = element.getName().getPrefix();
204
205 final Element currentElement;
206 if (StringUtils.isNotBlank(prefix))
207 {
208 final String uri = element.getNamespaceURI(prefix);
209 currentElement = document.createElementNS(uri, prefix + ':' + gi);
210 }
211 else
212 {
213 currentElement = document.createElement(gi);
214 }
215
216 final Element parentElement = elements.peek();
217 parentElement.appendChild(currentElement);
218 elements.push(currentElement);
219
220 for (final Iterator<Attribute> i = element.getAttributes(); i.hasNext();)
221 {
222 final Attribute attribute = i.next();
223 currentElement.setAttribute(attribute.getName().toString(),
224 attribute.getValue());
225 }
226 }
227
228
229
230 }