JAXP使用Stax API时格式化输出XML 2

之前实现的一个版本:http://www.cnblogs.com/lyhtbc/p/jaxp-pretty-format-validate-validation-stax-stax2.html

这个版本中存一个问题:如果某一个节点的值是空的话,会换行输出结束标签,如:

<a>

</a>

某些场景下会要求节点内必须要有值,否则就应该输出为 <a/>(例如XBRL instance的schemaLink节点)。

 

新代码如下:

XMLPrettyFormatter:

 1 import javax.xml.stream.XMLStreamException;
 2 
 3 /**
 4  * XML pretty formatter.
 5  */
 6 public interface XMLPrettyFormatter {
 7 
 8     enum NodeType {
 9         ELEMENT, VALUE, NULL
10     }
11 
12     String DEFAULT_INDENTION = "\t";
13 
14     void writeStartElementIndention() throws XMLStreamException;
15 
16     /**
17      * @param blankValue
18      *            True if the value is null of blank character.
19      */
20     void writeValueIndention(boolean blankValue) throws XMLStreamException;
21 
22     void writeEndElementIndention() throws XMLStreamException;
23 
24 }

DefaultPrettyFormatter:

 1 import java.util.LinkedList;
 2 
 3 import javax.xml.stream.XMLStreamException;
 4 
 5 import org.codehaus.stax2.XMLStreamWriter2;
 6 
 7 /**
 8  * Default XML pretty formatter.
 9  * <ol>
10  * <li>Default intention is tab character "\t".</li>
11  * <li>The value display in the same line with which element it belongs to.</li>
12  * <li>If value is blank, don't use separate end tag.</li>
13  * </ol>
14  */
15 public class DefaultPrettyFormatter implements XMLPrettyFormatter {
16 
17     private String indent = DEFAULT_INDENTION;
18 
19     private LinkedList<NodeType> stack = new LinkedList<XMLPrettyFormatter.NodeType>();
20 
21     private XMLStreamWriter2 writer;
22 
23     public DefaultPrettyFormatter(XMLStreamWriter2 writer) {
24         this.writer = writer;
25     }
26 
27     public DefaultPrettyFormatter(XMLStreamWriter2 writer, String indent) {
28         this.writer = writer;
29         this.indent = indent;
30     }
31 
32     @Override
33     public void writeStartElementIndention() throws XMLStreamException {
34         NodeType lastNode = stack.peek();
35         if (lastNode != null && lastNode == NodeType.NULL) {
36             stack.pop();
37         }
38         
39         writeLineBreaker();
40         for (int i = 0; i < stack.size(); ++i) {
41             writeIndention();
42         }
43         
44         stack.push(NodeType.ELEMENT);
45 
46         // default value node
47         stack.push(NodeType.NULL);
48     }
49 
50     @Override
51     public void writeValueIndention(boolean blankValue) throws XMLStreamException {
52         if (!blankValue) {
53             // if value is not blank, pop default blank node first.
54             stack.pop();
55             stack.push(NodeType.VALUE);
56         }
57     }
58 
59     @Override
60     public void writeEndElementIndention() throws XMLStreamException {
61         NodeType lastNode = stack.pop();
62         if (lastNode == NodeType.ELEMENT) {
63             writeLineBreaker();
64             for (int i = 0; i < stack.size(); ++i) {
65                 writeIndention();
66             }
67         } else {
68             // pop start element
69             stack.pop();
70         }
71     }
72 
73     private void writeLineBreaker() throws XMLStreamException {
74         writer.writeCharacters("\n");
75     }
76 
77     private void writeIndention() throws XMLStreamException {
78         writer.writeCharacters(indent.toCharArray(), 0, indent.length());
79     }
80 
81 }

 

posted @ 2014-04-18 14:33  小1  阅读(924)  评论(0编辑  收藏  举报