1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.esigate.xml;
17
18 import java.io.FilterWriter;
19 import java.io.IOException;
20 import java.io.Writer;
21 import java.util.Arrays;
22
23 import nu.validator.htmlparser.sax.HtmlSerializer;
24
25 import org.xml.sax.Attributes;
26 import org.xml.sax.SAXException;
27
28
29
30
31
32
33
34 public class XhtmlSerializer extends HtmlSerializer {
35 private static final String[] VOID_ELEMENTS = {"area", "base", "basefont", "bgsound", "br", "col", "command",
36 "embed", "frame", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"};
37 private final TagClosingWriter tagClosingWriter;
38
39 private static class TagClosingWriter extends FilterWriter {
40 private boolean fix = false;
41
42 protected TagClosingWriter(Writer out) {
43 super(out);
44 }
45
46 @Override
47 public void write(int c) throws IOException {
48 if (fix && c == '>') {
49 super.write(' ');
50 super.write('/');
51 }
52 super.write(c);
53 }
54
55 }
56
57 public XhtmlSerializer(Writer out) {
58 this(new TagClosingWriter(out));
59 }
60
61 private XhtmlSerializer(TagClosingWriter out) {
62 super(out);
63 this.tagClosingWriter = out;
64 }
65
66 @Override
67 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
68 if (Arrays.binarySearch(VOID_ELEMENTS, localName) > -1) {
69 tagClosingWriter.fix = true;
70 }
71 super.startElement(uri, localName, qName, atts);
72 tagClosingWriter.fix = false;
73 }
74
75 @Override
76 public void startDocument() {
77
78 }
79
80 }