Java解析xml文件

在Java程序中读取xml文件的过程也称为“解析xml文件”;

解析的目的:

  • 获取 节点名和节点值
  • 获取 属性名、属性值。

四中解析方式:

  • DOM
  • SAX
  • DOM4J
  • JDOM

(其中DOM、SAX是官方提供的解析方式,不需要额外的jar包,后两种则需要)



例:DOM方式解析books.xml文件

<?xml version="1.0" encoding="UTF-8" ?> 
<bookstore>
        <book type="fiction" id="1">
                <name>冰与火之歌</name>
                <author>乔治马丁</author>
                <year>2014</year>
                <price>89</price>
        </book>
        <book id="2">
                <name>安徒生童话</name>
                <year>2004</year>
                <price>77</price>
                <language>English</language>
        </book>
</bookstore>


15

 

1

<?xml version="1.0" encoding="UTF-8" ?>

2

<bookstore>

3

<book type="fiction" id="1">

4

<name>冰与火之歌</name>

5

<author>乔治马丁</author>

6

<year>2014</year>

7

<price>89</price>

8

</book>

9

<book id="2">

10

<name>安徒生童话</name>

11

<year>2004</year>

12

<price>77</price>

13

<language>English</language>

14

</book>

15

</bookstore>

以上是我们需要解析的xml文件,我们的目的是:通过Java获取xml文件的所有数据。


准备工作

准备工作:

  • (1)创建一个DocumentBuilderFactory对象
  • (2)创建一个DocumentBuilder对象
  • (3)通过DocumentBuilder对象的parse(String fileName)方法解析xml文件
public class DomTest { 
    public static void main(String[] args) {
        //(1)创建DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //(2)创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            //(3)通过DocumentBuilder对象的parse方法加载book.xml
            Document document = db.parse("books.xml");

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


19

 

1

public class DomTest {

2

public static void main(String[] args) {

3

//(1)创建DocumentBuilderFactory对象

4

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

5

try {

6

//(2)创建DocumentBuilder对象

7

DocumentBuilder db = dbf.newDocumentBuilder();

8

//(3)通过DocumentBuilder对象的parse方法加载book.xml

9

Document document = db.parse("books.xml");

10

11

} catch (ParserConfigurationException e) {

12

e.printStackTrace();

13

} catch (SAXException e) {

14

e.printStackTrace();

15

} catch (IOException e) {

16

e.printStackTrace();

17

}

18

}

19

}


解析xml文件属性

java解析复杂xml成json数据 java如何解析xml_xml

解析属性:

  • (1)Document类来获取节点集合
  • (2)遍历节点集合
  • (3)通过item(i)获取节点Node
  • (4)通过Node的getAttributes获取节点的属性集合
  • (5)遍历属性
  • (6)获取属性和属性名


public class DomTest { 
    public static void main(String[] args) {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            //通过DocumentBuilder对象的parse方法加载book.xml
            Document document = db.parse("books.xml");

            //(1)获取所有book节点的集合
            NodeList booklist = document.getElementsByTagName("book");
            System.out.println("共有" + booklist.getLength() + "本书");
            System.out.println("-------------------------------------");

            //(2)遍历每个book节点
            for (int i = 0; i < booklist.getLength(); i++) {
                //(3)通过item(i)获取book节点,nodelist索引从0开始
                Node book = booklist.item(i);
                //(4)获取book节点的所有属性集合
                NamedNodeMap attrs = book.getAttributes();

                //获取属性的数量
                System.out.println("第" + (i + 1) + "本书有" + attrs.getLength() + "个属性");
                System.out.print("分别是:");

                //(5)遍历book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    //(6)获取属性
                    Node att = attrs.item(j);
                    //(6)获取属性的名称
                    String attName = att.getNodeName();
                    System.out.print(attName + ", ");
                }
                System.out.println();
                System.out.println("-------------------------------------");
            }

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


47

 

1

public class DomTest {

2

public static void main(String[] args) {

3

//创建DocumentBuilderFactory对象

4

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

5

try {

6

//创建DocumentBuilder对象

7

DocumentBuilder db = dbf.newDocumentBuilder();

8

//通过DocumentBuilder对象的parse方法加载book.xml

9

Document document = db.parse("books.xml");

10

11

//(1)获取所有book节点的集合

12

NodeList booklist = document.getElementsByTagName("book");

13

System.out.println("共有" + booklist.getLength() + "本书");

14

System.out.println("-------------------------------------");

15

16

//(2)遍历每个book节点

17

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

18

//(3)通过item(i)获取book节点,nodelist索引从0开始

19

Node book = booklist.item(i);

20

//(4)获取book节点的所有属性集合

21

NamedNodeMap attrs = book.getAttributes();

22

23

//获取属性的数量

24

System.out.println("第" + (i + 1) + "本书有" + attrs.getLength() + "个属性");

25

System.out.print("分别是:");

26

27

//(5)遍历book的属性

28

for (int j = 0; j < attrs.getLength(); j++) {

29

//(6)获取属性

30

Node att = attrs.item(j);

31

//(6)获取属性的名称

32

String attName = att.getNodeName();

33

System.out.print(attName + ", ");

34

}

35

System.out.println();

36

System.out.println("-------------------------------------");

37

}

38

39

} catch (ParserConfigurationException e) {

40

e.printStackTrace();

41

} catch (SAXException e) {

42

e.printStackTrace();

43

} catch (IOException e) {

44

e.printStackTrace();

45

}

46

}

47

}

打印结果:

共有2本书 
-------------------------------------
第1本书有2个属性
分别是:id, type, 
-------------------------------------
第2本书有1个属性
分别是:id, 
-------------------------------------


8

 

1

共有2本书

2

-------------------------------------

3

第1本书有2个属性

4

分别是:id, type,

5

-------------------------------------

6

第2本书有1个属性

7

分别是:id,

8

-------------------------------------


解析xml文件属性的子节点

解析子节点:

  • (1)使用getChildNodes()获取子节点集合
  • (2)遍历子节点
  • (3)获取子节点
  • (4)输出子节点名称和内容
public class DomTest { 
    public static void main(String[] args) {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            //通过DocumentBuilder对象的parse方法加载book.xml
            Document document = db.parse("books.xml");

            //获取所有book节点的集合
            NodeList booklist = document.getElementsByTagName("book");
            System.out.println("共有" + booklist.getLength() + "本书");
            System.out.println("-------------------------------------");

            //遍历每个book节点
            for (int i = 0; i < booklist.getLength(); i++) {
                //通过item(i)获取book节点,nodelist索引从0开始
                Node book = booklist.item(i);
                //获取book节点的所有属性集合
                NamedNodeMap attrs = book.getAttributes();

                //获取属性的数量
                System.out.println("第" + (i + 1) + "本书有" + attrs.getLength() + "个属性");
                System.out.print("分别是:");

                //遍历book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    //获取属性
                    Node att = attrs.item(j);
                    //获取属性的名称
                    String attName = att.getNodeName();
                    System.out.print(attName + ", ");
                }
                System.out.println();

                System.out.println("子节点:");
                //(1)解析book节点的子节点
                NodeList bookChildNodes = book.getChildNodes();
                //(2)遍历bookChildNodes获取每个子节点
                for (int k = 0; k < bookChildNodes.getLength(); k++) {
                    //(3)获取子节点
                    Node bookChild = bookChildNodes.item(k);

                    //注(a)
                    //区分text类型的node以及element类型的node(子节点含我们不需要的文本型,所以我们要筛选)
                    if (bookChild.getNodeType() == Node.ELEMENT_NODE) {
                        //注(b)
                        //(4)获取和输出节点名和节点内容
                        //方法1:
                        System.out.println(bookChild.getNodeName() + ",  " + bookChild.getTextContent());
                        //方法2:
                        //System.out.println(bookChild.getNodeName() + ",  " + bookChild.getFirstChild().getNodeValue());
                    }

                }
                System.out.println("-------------------------------------");
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


x

 

1

public class DomTest {

2

public static void main(String[] args) {

3

//创建DocumentBuilderFactory对象

4

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

5

try {

6

//创建DocumentBuilder对象

7

DocumentBuilder db = dbf.newDocumentBuilder();

8

//通过DocumentBuilder对象的parse方法加载book.xml

9

Document document = db.parse("books.xml");

10

11

//获取所有book节点的集合

12

NodeList booklist = document.getElementsByTagName("book");

13

System.out.println("共有" + booklist.getLength() + "本书");

14

System.out.println("-------------------------------------");

15

16

//遍历每个book节点

17

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

18

//通过item(i)获取book节点,nodelist索引从0开始

19

Node book = booklist.item(i);

20

//获取book节点的所有属性集合

21

NamedNodeMap attrs = book.getAttributes();

22

23

//获取属性的数量

24

System.out.println("第" + (i + 1) + "本书有" + attrs.getLength() + "个属性");

25

System.out.print("分别是:");

26

27

//遍历book的属性

28

for (int j = 0; j < attrs.getLength(); j++) {

29

//获取属性

30

Node att = attrs.item(j);

31

//获取属性的名称

32

String attName = att.getNodeName();

33

System.out.print(attName + ", ");

34

}

35

System.out.println();

36

37

System.out.println("子节点:");

38

//(1)解析book节点的子节点

39

NodeList bookChildNodes = book.getChildNodes();

40

//(2)遍历bookChildNodes获取每个子节点

41

for (int k = 0; k < bookChildNodes.getLength(); k++) {

42

//(3)获取子节点

43

Node bookChild = bookChildNodes.item(k);

44

45

//注(a)

46

//区分text类型的node以及element类型的node(子节点含我们不需要的文本型,所以我们要筛选)

47

if (bookChild.getNodeType() == Node.ELEMENT_NODE) {

48

//注(b)

49

//(4)获取和输出节点名和节点内容

50

//方法1:

51

System.out.println(bookChild.getNodeName() + ",  " + bookChild.getTextContent());

52

//方法2:

53

//System.out.println(bookChild.getNodeName() + ",  " + bookChild.getFirstChild().getNodeValue());

54

}

55

56

}

57

System.out.println("-------------------------------------");

58

}

59

} catch (ParserConfigurationException e) {

60

e.printStackTrace();

61

} catch (SAXException e) {

62

e.printStackTrace();

63

} catch (IOException e) {

64

e.printStackTrace();

65

}

66

}

67

}

打印结果:

共有2本书 
-------------------------------------
第1本书有2个属性
分别是:id, type, 
子节点:
name,  test冰与火之歌
author,  乔治马丁
year,  2014
price,  89
-------------------------------------
第2本书有1个属性
分别是:id, 
子节点:
name,  安徒生童话
year,  2004
price,  77
language,  English
-------------------------------------


18

 

1

共有2本书

2

-------------------------------------

3

第1本书有2个属性

4

分别是:id, type,

5

子节点:

6

name,  test冰与火之歌

7

author,  乔治马丁

8

year,  2014

9

price,  89

10

-------------------------------------

11

第2本书有1个属性

12

分别是:id,

13

子节点:

14

name,  安徒生童话

15

year,  2004

16

price,  77

17

language,  English

18

-------------------------------------



java解析复杂xml成json数据 java如何解析xml_java解析复杂xml成json数据_02

 

注(a):解析时是把空白也算为文本型的子节点,如下看似只有4个子节点,算上空白会输出9个子节点。

<bookstroe> 
  <book id="1">  
      <name>冰与火之歌</name>  
      <author>乔治马丁</author>  
      <year>2014</year>  
      <price>89</price>  
  </book>
</bookstroe


8

 

1

<bookstroe>

2

<book id="1">

3

<name>冰与火之歌</name>

4

<author>乔治马丁</author>

5

<year>2014</year>

6

<price>89</price>

7

</book>

8

</bookstroe

如上图所示,黄色和橙色也都算成了text类型的节点,这是我们不需要的,往往需要判断筛选。


java解析复杂xml成json数据 java如何解析xml_System_03

<bookstroe> 
  <book id="1">  
      <name>冰与火之歌</name>  
      <author>乔治马丁</author>  
      <year>2014</year>  
      <price>89</price>  
  </book>
</bookstroe>


 

1

<bookstroe>

2

<book id="1">

3

<name>冰与火之歌</name>

4

<author>乔治马丁</author>

5

<year>2014</year>

6

<price>89</price>

7

</book>

8

</bookstroe>

注(b):假如此时我们想要获取<name>中的“冰与火之歌”

1)获取子节点的内容的时候,不是使用getNodeValue(),如上图,该方法只会返回null;我们要使用getTextContent()来获取两个标签中间的内容;

2)另外,也可以使用获取这个子节点的子节点,之前有提到,text也被视为子节点,这里的“冰与火之歌”被视为<name>的子节点,所以获取子节点的子节点以后,再使用getNodeValue()才有意义,即先获取book的子节点<name>,再获取name的子节点;

3)这两种方法的区别:

假如有<name><a>test</a>冰与火之歌</name>

getTextContext() --> test冰与火之歌(获取name下所有的文本并拼接起来)

getFirstChild().getNodeValue() --> null(获得子节点并输出其值)



如何在Java中保留xml数据的结构?

创建一个Book类,包含属性name、author、year、price等,在解析该xml的同时,就对该对象中的属性进行赋值。

当然,多个对象的时候,自然还需要存到集合中去。


附件列表