Java SAX解析XML

网友投稿 846 2022-05-30

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

Java SAX解析XML

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小时内删除侵权内容。

上一篇:ABAP Netweaver, Hybris Commerce和SAP 云平台的登录认证
下一篇:一种基于数据库与渲染模板的代码生成器——模板渲染
相关文章