1
package org.htmlcleaner;
5
import java.util.HashMap;
6
import java.util.Iterator;
11
* <p>JDom serializer - creates xml JDom instance out of the TagNode.</p>
13
public class JDomSerializer {
15
private DefaultJDOMFactory factory;
17
protected CleanerProperties props;
18
protected boolean escapeXml = true;
20
public JDomSerializer(CleanerProperties props, boolean escapeXml) {
22
this.escapeXml = escapeXml;
25
public JDomSerializer(CleanerProperties props) {
29
public Document createJDom(TagNode rootNode) {
30
this.factory = new DefaultJDOMFactory();
31
Element rootElement = createElement(rootNode);
32
Document document = this.factory.document(rootElement);
34
setAttributes(rootNode, rootElement);
36
createSubnodes(rootElement, rootNode.getChildren());
41
private Element createElement(TagNode node) {
42
String name = node.getName();
43
boolean nsAware = props.isNamespacesAware();
44
String prefix = Utils.getXmlNSPrefix(name);
45
Map<String, String> nsDeclarations = node.getNamespaceDeclarations();
48
name = Utils.getXmlName(name);
50
if (nsDeclarations != null) {
51
nsURI = nsDeclarations.get(prefix);
54
nsURI = node.getNamespaceURIOnPath(prefix);
62
if (nsDeclarations != null) {
63
nsURI = nsDeclarations.get("");
66
nsURI = node.getNamespaceURIOnPath(prefix);
72
if (nsAware && nsURI != null) {
73
Namespace ns = prefix == null ? Namespace.getNamespace(nsURI) : Namespace.getNamespace(prefix, nsURI);
74
element = factory.element(name, ns);
76
element = factory.element(name);
80
defineNamespaceDeclarations(node, element);
85
private void defineNamespaceDeclarations(TagNode node, Element element) {
86
Map<String, String> nsDeclarations = node.getNamespaceDeclarations();
87
if (nsDeclarations != null) {
88
for (Map.Entry<String, String> nsEntry: nsDeclarations.entrySet()) {
89
String nsPrefix = nsEntry.getKey();
90
String nsURI = nsEntry.getValue();
91
Namespace ns = nsPrefix == null || "".equals(nsPrefix) ? Namespace.getNamespace(nsURI) : Namespace.getNamespace(nsPrefix, nsURI);
92
element.addNamespaceDeclaration(ns);
97
private void setAttributes(TagNode node, Element element) {
98
for (Map.Entry<String, String> entry: node.getAttributes().entrySet()) {
99
String attrName = entry.getKey();
100
String attrValue = entry.getValue();
102
attrValue = Utils.escapeXml(attrValue, props, true);
104
String attPrefix = Utils.getXmlNSPrefix(attrName);
106
if (attPrefix != null) {
107
attrName = Utils.getXmlName(attrName);
108
if (props.isNamespacesAware()) {
109
String nsURI = node.getNamespaceURIOnPath(attPrefix);
113
ns = Namespace.getNamespace(attPrefix, nsURI);
117
element.setAttribute(attrName, attrValue);
119
element.setAttribute(attrName, attrValue, ns);
124
private void createSubnodes(Element element, List tagChildren) {
125
if (tagChildren != null) {
126
Iterator it = tagChildren.iterator();
127
while (it.hasNext()) {
128
Object item = it.next();
129
if (item instanceof CommentNode) {
130
CommentNode commentNode = (CommentNode) item;
131
Comment comment = factory.comment( commentNode.getContent().toString() );
132
element.addContent(comment);
133
} else if (item instanceof ContentNode) {
134
String nodeName = element.getName();
135
String content = item.toString();
136
boolean specialCase = props.isUseCdataForScriptAndStyle() &&
137
("script".equalsIgnoreCase(nodeName) || "style".equalsIgnoreCase(nodeName));
138
if (escapeXml && !specialCase) {
139
content = Utils.escapeXml(content, props, true);
141
Text text = specialCase ? factory.cdata(content) : factory.text(content);
142
element.addContent(text);
143
} else if (item instanceof TagNode) {
144
TagNode subTagNode = (TagNode) item;
145
Element subelement = createElement(subTagNode);
147
setAttributes(subTagNode, subelement);
149
// recursively create subnodes
150
createSubnodes(subelement, subTagNode.getChildren());
152
element.addContent(subelement);
153
} else if (item instanceof List) {
154
List sublist = (List) item;
155
createSubnodes(element, sublist);