還在用絲襪哥(Swagger)做API文檔?快來看看這款幫你減少百分之九十工作量的開源工具!
955
2025-04-03
SAX解析XML采用的是從上而下的基于事件驅動的解析方式,在解析過程中會視情況自動調用startDocument()、startElement()、characters()、endElement()、endDocument()等相關的方法。
由編譯執行的結果來看:
startDocument()方法只會在文檔開始解析的時候被調用,每次解析只會調用一次。
startElement()方法每次在開始解析一個元素,即遇到元素標簽開始的時候都會調用。
characters()方法也是在每次解析到元素標簽攜帶的內容時都會調用,即使該元素標簽的內容為空或換行。而且如果元素內嵌套元素,在父元素結束標簽前, characters()方法會再次被調用,此處需要注意。
endElement()方法每次在結束解析一個元素,即遇到元素標簽結束的時候都會調用。
endDocument() startDocument()方法只會在文檔解析結束的時候被調用,每次解析只會調用一次。
oracle官方解析教程 http://docs.oracle.com/javase/tutorial/jaxp/sax/parsing.html
package com.demo.test; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; public class XmlDemo { private static class SAXHandler extends DefaultHandler { @Override public void startDocument() throws SAXException { System.out.println("startDocument"); } @Override public void endDocument() throws SAXException { System.out.println("endDocument"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("startElement, uri=" + uri + ", localName=" + localName + ", qName=" + qName + ", attributes.getLength()=" + attributes.getLength()); if (attributes.getLength() > 0) { for (int i = 0; i < attributes.getLength(); i++) { System.out.println("startElement attributes(" + i + "): " + attributes.getQName(i) + "=" + attributes.getValue(i)); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("endElement, uri=" + uri + ", localName=" + localName + ", qName=" + qName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.println("characters, start=" + start + ", length=" + length + ", ch=" + new String(ch, start, length)); } } private static void parseXml(String xmlPath) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); FileInputStream fis = null; try { fis = new FileInputStream(xmlPath); InputSource is = new InputSource(fis); // SAX會自動從流中檢測正確的字符編碼,但是如果流中沒有明確指定編碼,可能會導致轉換錯誤 is.setEncoding("UTF-8"); SAXParser saxParser = saxParserFactory.newSAXParser(); saxParser.parse(is, new SAXHandler()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } private static void generateXml(String filePath) { SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); FileOutputStream fos = null; try { TransformerHandler transformerHandler = saxTransformerFactory.newTransformerHandler(); Transformer transformer = transformerHandler.getTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 如果是yes,那么會自動換行但不會縮進;如果是no,則不會換行。默認是no // transformer.setOutputProperty(OutputKeys.INDENT, "no"); //不省略的話,會自動添加。默認是no transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); fos = new FileOutputStream(filePath); Result result = new StreamResult(fos); transformerHandler.setResult(result); transformerHandler.startDocument(); AttributesImpl attr = new AttributesImpl(); attr.addAttribute(null, null, "class", String.class.getName(), "value"); startElement(transformerHandler, "html", null); startElement(transformerHandler, "head", null); endElement(transformerHandler, "head"); startElement(transformerHandler, "body", null); selfEndElement(transformerHandler, "p", attr, "characters"); endElement(transformerHandler, "body"); endElement(transformerHandler, "html"); transformerHandler.endDocument(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } // SAX默認不自動縮進,因此需要手動根據元素層次進行縮進控制 private static int indent = 0; private static String uri = "http://www.chy.uri"; private static String localname = "localname"; // private static String uri = null; // private static String localname = null; private static void startElement(TransformerHandler transformerHandler, String qName, Attributes atts) throws SAXException { System.out.println("startElement " + qName); indent++; addTabs(transformerHandler); transformerHandler.startElement(uri, localname, qName, atts); } private static void endElement(TransformerHandler transformerHandler, String qName) throws SAXException { System.out.println("endElement " + qName); addTabs(transformerHandler); indent--; transformerHandler.endElement(uri, localname, qName); } /** * 自封閉式標簽 */ private static void selfEndElement(TransformerHandler transformerHandler, String qName, Attributes atts, String str) throws SAXException { System.out.println("endElement " + qName); indent++; addTabs(transformerHandler); indent--; transformerHandler.startElement(uri, localname, qName, atts); if (str != null) { char[] charArr = str.toCharArray(); transformerHandler.characters(charArr, 0, charArr.length); } transformerHandler.endElement(uri, localname, qName); } /** * SAX不會添加縮進,要自己添加 */ private static void addTabs(TransformerHandler transformerHandler) throws SAXException { System.out.println("addTabs " + indent); char[] ch = new char[indent]; ch[0] = '\n'; if (indent > 1) { for (int i = 1; i < ch.length; i++) { ch[i] = '\t'; } } transformerHandler.characters(ch, 0, ch.length); } public static void main(String[] args) { String xmlPath = "test.xml"; parseXml(xmlPath); generateXml("test.xml"); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
生成的XML如下
characters
1
2
3
4
5
6
7
8
這里如果uri變量設置為空,會自動生成一個無結束標簽的META標簽,并且indent設置為no也無效,還是會自動換行
characters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
右擊項目 –> Properties(Alt + Enter)–> Java Build Path –> Libraries –> 雙擊JRE System Library
注意:這里如果選擇OSGi/Minimum-1.2是找不到”javax.xml.“或”org.xml.sax.”的相關包的。最低版本必須是J2SE-1.5。
Java XML
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。