Java解析XML文件的方式(1),精心整理

17 NodeList books = root.getChildNodes();

整个XML文件包含在第13行定义的doc对象里,在第15行里,我们通过getDocumentElement方法得到了根节点(也就是books节点),在第17行,通过getChildNoes方法得到该books节点下的所有子节点,随后开始解析整个xml文档。

需要说明的是,在解析前,我们会通过观察xml文档来了解其中的元素名和属性名,所以在后继的代码里,我们会针对元素名和属性名进行编程。

18 if(books!=null){

19 for(int i=0;i<books.getLength();i++){

20 Node book=books.item(i);

21 //获取id属性

22 if(book.getNodeType()==Node.ELEMENT_NODE){

23 String id=book.getAttributes().getNamedItem(“id”).getNodeValue();

24 System.out.println(“id is:” + id);

25 //遍历book下的子节点

26 for(Node node=book.getFirstChild(); node!=null;node=node.getNextSibling()){

27 if(node.getNodeType()==Node.ELEMENT_NODE){

28 //依次读取book里的name,price和memo三个子元素

29 if(node.getNodeName().equals(“name”)){

30 String name=node.getFirstChild().getNodeValue();

31 System.out.println(“name is:” + name);

32 }

33 if(node.getNodeName().equals(“price”)){

34 String price=node.getFirstChild().getNodeValue();

35 System.out.println(“price is:” + price);

36 }

37 if(node.getNodeName().equals(“memo”)){

38 String memo=node.getFirstChild().getNodeValue();

39 System.out.println(“memo is:” + memo);

40 }

41 }

42 }

43 }

44 }

45 }

第19行的for循环里,我们是遍历book元素通过观察xml文件,我们发现book元素出现了2次,所有这个循环会运行两次,而且,book元素有1个id属性,所有我们需要通过第23行的代码,得到id属性的值。

在文档里,book元素有3个子节点,分别是name,price和memo,所以在代码的26行里,再次使用for循环遍历其中的子节点。在遍历时,我们通过29到32行的代码获取到了book元素里name的值,通过类似的代码后继的33到40行代码里得到了price和memo这两个元素的值。

46 } catch (ParserConfigurationException e) {

47 e.printStackTrace();

48 } catch (FileNotFoundException e) {

49 e.printStackTrace();

50 } catch (IOException e) {

51 e.printStackTrace();

52 } catch (SAXException e) {

53 e.printStackTrace();

54 } catch (Exception e) {

55 e.printStackTrace();

56 }

57 //在finally里关闭io流

58 finally{

59 try {

60 input.close();

61 } catch (IOException e) {

62 e.printStackTrace();

63 }

64 }

65 }

66 }

同样地,在解析完成后,在finally从句里,我们关闭了之前用到的IO流(input对象)。

3 基于事件的解析方式

SAX是Simple API for XML的缩写,不同于DOM的文档驱动,它是事件驱动的,也就是说,它是一种基于回调(callback)函数的解析方式,比如开始解析xml文档时,会调用我们自己定义的startDocument函数,从下表里,我们能看到基于SAX方式里的各种回调函数以及它们被调用的时间点。

函数名

调用时间点

startDocument

开始解析xml文档时(解析xml文档第一个字符时)会被调用

endDocument

当解析完xml文档时(解析到xml文档最后一个字符时)会被调用

startElement

当解析到开始标签时会被调用,比如在解析“<name>FrameWork</name>”这个element时,当读到开始标签“<name>”时,会被调用

endElement

当解析到结束标签时会被调用,比如在解析“<name>FrameWork</name>”这个element时,当读到结束标签“</name>”时,会被调用

characters

1行开始后,遇到开始或结束标签之前存在字符,则会调用

2两个标签之间,存在字符,则会调用,比如在解析“<name>FrameWork</name>”时,发现存在FrameWork,则会被调用

3标签和行结束符之前存在字符,则会调用

从上表里我们能看到characters方法会在多个场合被回调,但我们最期望的调用场景是第2种,这就要求我们最好在解析xml文档前整理下它的格式,尽量避免第1和第3种情况。在ParserXmlBySAX.java这个案例中,我们通过了编写上述的回调函数,实现了SAX方式解析xml文档的功能。

1 //省略import的代码

2 //基于SAX的解析代码需要继承DefaultHandler类

3 public class ParserXmlBySAX extends DefaultHandler{

4 // 记录当前解析到的节点名

5 private String tagName;

6 //主方法

7 public static void main(String[] argv) {

8 String uri = “src/book.xml”;

9 try {

10 SAXParserFactory parserFactory = SAXParserFactory.newInstance();

11 ParserXmlBySAX myParser = new ParserXmlBySAX();

12 SAXParser parser = parserFactory.newSAXParser();

13 parser.parse(uri, myParser);

14 } catch (IOException ex) {

15 ex.printStackTrace();

16 } catch (SAXException ex) {

17 ex.printStackTrace();

18 } catch (ParserConfigurationException ex) {

19 ex.printStackTrace();

20 } catch (FactoryConfigurationError ex) {

21 ex.printStackTrace();

22 }

23 }

在main方法的第8行里,我们指定了待解析xml文档的路径和文件名,在第10行里,我们创建了SAXParserFactory这个类型的SAX解析工厂对象。在第12行,我们通过SAX解析工厂对象,创建了SAXParser这个类型的解析类。在第13行,通过了parse方法启动了解析。

在上文里我们就已经知道,在SAX的方式里,是通过调用各种回调函数来完成解析的,所以在代码里,我们还得自定义各个回调函数,代码如下。

// 处理到文档结尾时,直接输出,不做任何动作

25 public void endDocument() throws SAXException {

26 System.out.println(“endDocument”);

27 }

28 // 处理到结束标签时,把记录当前标签名的tagName设置成null

29 public void endElement(String uri, String localName, String qName) throws SAXException {

30 tagName = null;

31 }

32 // 开始处理文档时,直接输出,不做任何动作

33 public void startDocument() throws SAXException {

34 System.out.println(“startDocument”);

35 }

36 // 处理开始标签

37 public void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException {

38 if (“book”.equals(name)) { //解析book标签的属性

39 for (int i = 0; i < attributes.getLength(); i++) {

40 System.out.println(“attribute name is:” + attributes.getLocalName(i) + " attribute value:" + attributes.getValue(i));

41 }

42 }

43 //把当前标签的名字记录到tagName这个变量里

44 tagName = name;

45 }

46 //通过这个方法解析book的三个子元素的值

47 public void characters(char[] ch, int start, int length)

48 throws SAXException {

49 if(this.tagName!=null){

50 String val=new String(ch,start,length);

51 //如果是name,price或memo,则输出它们的值

52 if(“name”.equals(tagName))

53 { System.out.println(“name is:” + val); }

54 if(“price”.equals(tagName))

55 { System.out.println(“price is:” + val); }

56 if(“memo”.equals(tagName))

57 { System.out.println(“memo is:” + val); }

58 }

59 }

60 }

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

为什么我不完全主张自学?
平台上的大牛基本上都有很多年的工作经验了,你有没有想过之前行业的门槛是什么样的,现在行业门槛是什么样的?以前企业对于程序员能力要求没有这么高,甚至十多年前你只要会写个“Hello World”,你都可以入门这个行业,所以以前要入门是完全可以入门的。
②现在也有一些优秀的年轻大牛,他们或许也是自学成才,但是他们一定是具备优秀的学习能力,优秀的自我管理能力(时间管理,静心坚持等方面)以及善于发现问题并总结问题。
如果说你认为你的目标十分明确,能做到第②点所说的几个点,以目前的市场来看,你才真正的适合去自学。

除此之外,对于绝大部分人来说,报班一定是最好的一种快速成长的方式。但是有个问题,现在市场上的培训机构质量参差不齐,如果你没有找准一个好的培训班,完全是浪费精力,时间以及金钱,这个需要自己去甄别选择。

我个人建议线上比线下的性价比更高,线下培训价格基本上没2W是下不来的,线上教育现在比较成熟了,此次疫情期间,学生基本上都感受过线上的学习模式。相比线下而言,线上的优势以我的了解主要是以下几个方面:
①价格:线上的价格基本上是线下的一半;
②老师:相对而言线上教育的师资力量比线下更强大也更加丰富,资源更好协调;
③时间:学习时间相对而言更自由,不用裸辞学习,适合边学边工作,降低生活压力;
④课程:从课程内容来说,确实要比线下讲的更加深入。

应该学哪些技术才能达到企业的要求?(下图总结)

下的性价比更高,线下培训价格基本上没2W是下不来的,线上教育现在比较成熟了,此次疫情期间,学生基本上都感受过线上的学习模式。相比线下而言,线上的优势以我的了解主要是以下几个方面:
①价格:线上的价格基本上是线下的一半;
②老师:相对而言线上教育的师资力量比线下更强大也更加丰富,资源更好协调;
③时间:学习时间相对而言更自由,不用裸辞学习,适合边学边工作,降低生活压力;
④课程:从课程内容来说,确实要比线下讲的更加深入。

应该学哪些技术才能达到企业的要求?(下图总结)

[外链图片转存中…(img-4KzjKanv-1712091106445)]

[外链图片转存中…(img-itTHKAxo-1712091106445)]

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值