文章目录

  • 了解xml
    • xml文件的结构
      • **特殊处理**
      • **CDATA**
    • 强烈建议
  • 处理xml文件的几种方式
    • 认识Document对象
    • 解析xml文档
      • 该选择哪种方式解析
    • DOM解析xml文件
    • DOM4j解析xml文档
    • SAX方式解析xml

了解xml

xml全称(Extensible Markup Language)可扩展标记语言。
xml和HTML属于同宗同源,都是SGML的衍生语言,下面是两者之间的区别:

  • xml是大小写敏感的,例如<H1>h和<h1>是不同的xml标签;
  • 在xml中,属性值必须用引号括起来,在HTML中,引号是可有可无的,例如,<applet code="MyApplet.class" width=300>对于HTML来说是合法的,在xml中,必须使用引号,比如<applet width="300">
  • xml中,属性名必须有值,HTML中可以没有值,例如<applet code="MyApplet.class" width>对HTML是合理的,但是对xml来时就是错误的,width属性必须有值,<applet code="MyApplet.class" width=“300”>
    xml需要注意的是注释中不能有–,否则会报错,如<!--这是错误--的注释-->错误后面的–是不能加的。

xml文件的结构

1、文件头
ML文件头由XML声明与DTD文件类型声明组成。其中DTD文件类型声明是可以缺少的,XML声明:

<?xml version="1.0" encoding="gb2312"?>

XML声明必须出现在文档的第一行。
2、文件体
有元素和元素属性组成,
3、约束文档
详解参考: https://blog.csdn.net/weixin_43790613/article/details/112425316
这个可有可无,可以提供一个文档类型定义(DTD)或一个XML Schema定义。作用是包含了用于解释文档应如何构成的规则,这些规则指定了每个元素的合法子元素和属性。不能添加指定外的元素和属性。
4. 命名空间:详解参考: https://blog.csdn.net/weixin_43790613/article/details/112451194

特殊处理

实体引用
实体引用是指分析文档时会被字符数据取代的元素,实体引用用于XML文档中的特殊字符,否则这些字符会被解释为元素的组成部分。例如,如果要显示“<”,需要使用实体引用“<”否则会被解释为一个标记的起始。

CDATA

在XML中由一个特殊的标记CDATA,在CDATA中所有文本都不会被XML处理器解释,直接显示在浏览器中,使用方法如下:
<![CDATA[ 这里的内容可以直接显示。 ]]>

强烈建议

对于属性,一个常用的经验法则是,属性只应用来节点值得解释,而不是用来指定值,如正确的用法是

<font name="姓名" age="年龄"><name>张三</name><age>18</age>
</font>

错误的用法:

<font name="张三" age="18">
</font>

处理xml文件的几种方式

DOM,SAX,JDOM和DOM4J等;DOM和SAX是解析方式,JDOM和DOM4J是解析开发包;jsoup也是xml解析开发包,但解析HTML更加方便

认识Document对象

Document对象时xml文档的树形结构在内存中的表现,它由实现了Node接口及其子接口的对象构成
各个子接口的层次结构

解析xml文档

要处理xml文档,就要先解析它。解析器是这样一个程序:它读入一个文件,确认这个文件具有正确的格式,然后将其分解成各种元素,是的程序员能够访问这些元素。java库提供了两种xml解析器:

  • 文档对象模型(Document Object Model,DOM)解析器这样的树形解析器,它们将读入的xml整个文档转换成树结构。
  • XML简单API(Simple API for XML,SAX)解析器这样的流机制解析器,它们在读入xml文档时生成相应的事件。

该选择哪种方式解析

DOM解析器对于实现我们大多数目的来说更容易些,缺点是它需要读取整个文档到内存,需要消耗较多内存,如果文档过大,那就建议使用SAX方式读取文件

DOM解析xml文件

JDK中包含DOM解析器,所以不需要额外的jar包或依赖。
要读入一个XML文档,首先需要一个DocumentBuilder对象,可以从DocumentBuilderFactory中获取
解析前xml文档

<?xml version="1.0" encoding="gb2312"?>
<grandfather><import location="http://localhost:8000/user?wsdl=IUserService.wsdl" namespace="http://webservice.com/"></import><parent><son></son></parent><son></son>
</grandfather>

解析代码

try{DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();InputStream resourceAsStream = App.class.getClassLoader().getResourceAsStream("test1.xml");Document document = builder.parse(resourceAsStream);// getDocumentElement将返回根元素Element documentElement = document.getDocumentElement();// 通过节点名称获取所有此节点名称的节点NodeList sonNodeList = documentElement.getElementsByTagName("son");// 构建子节点,此节点可以添加到任意节点下Element name = document.createElement("name");name.setTextContent("姓名");for (int i = 0; i < sonNodeList.getLength(); i++) {// 获取指定索引的节点Node item = sonNodeList.item(i);// 可以用此判断只获取子节点if (item instanceof Element){Element element = (Element) item;System.out.println(element.getTextContent());// 添加子节点的方法element.appendChild(name);System.out.println(i);}}// 获取节点中的文本内容,一般要用trim方法,否则会有换行符String textContent = documentElement.getTextContent().trim();// 获取指定属性的值String location = documentElement.getAttribute("location");documentElement.setAttribute("test","测试属性");// 返回子节点的集合,此方法如果xml文件中没有DTD文件,则返回的除了子节点外还有节点之间的空格信息NodeList childNodes = documentElement.getChildNodes();//将构建好的xml输出到指定文件TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();;
//             输出内容是否使用换行transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//            输出到文件//transformer.transform(new DOMSource(document), new StreamResult(new File("language.xml")));File file = new File("language.xml");
//            file.createNewFile();FileWriter fileWriter = new FileWriter(file);// 之前用的file可以,但是后来就不行了,包文件名、目录名或卷标语法不正确。,改成filewrite就可以了transformer.transform(new DOMSource(document), new StreamResult(fileWriter));
}catch (Exception e){e.printStackTrace();
}

生成的文档

<?xml version="1.0" encoding="GB2312" standalone="no"?>
<grandfather test="测试属性"><import location="http://localhost:8000/user?wsdl=IUserService.wsdl" namespace="http://webservice.com/"></import><parent><son></son></parent><son><name>姓名</name>
</son>
</grandfather>

废了很大劲就是没有用代码将生成的xml文件格式化好,如有大佬知道,还望不吝赐教。还有就是name节点只在

DOM4j解析xml文档

需要用到的依赖

<dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version>
</dependency>
<!--使用xpath用到的依赖-->
<dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.1-beta-8</version>
</dependency>
try {InputStream resourceAsStream = App.class.getClassLoader().getResourceAsStream("test1.xml");SAXReader saxReader = new SAXReader();Document document = saxReader.read(resourceAsStream);// 通过xpath获取节点Node node = document.selectSingleNode("/grandfather/parent/son");String sonNod = node.getText();System.out.println("zijiediandenrirong:" + sonNod);// 通过xpath获取节点并获取节点的属性
//            document.// 获取根节点Element rootElement = document.getRootElement();// 获取属性值Attribute attribute = (Attribute)rootElement.selectSingleNode("/grandfather/import/@location");String value = attribute.getValue();System.out.println("属性值" + value);// 普通方法获取节点对象直接点element()方法即可,这种只能获取子节点Element sonElement = rootElement.element("子节点的节点名称");// 获取根节点下面的子节点Element anImport = rootElement.element("import");// 会获取匹配到的符合条件的节点就返回此节点,即哪个节点靠前就返回哪个节点Node sonN = rootElement.selectSingleNode("//son");// 表示不分任何层次结构的选择元素String sonNo = sonN.getText();System.out.println("22222222:" + sonNo);List<Node> sonNode = rootElement.selectNodes("//son");for (Node node1: sonNode) {String sonNod1 = node1.getText();System.out.println("111111111111:" + sonNod1);}// 添加节点和属性Node node1 = rootElement.addElement("person");node1.setText("新增加的节点");// 设置生成xml的格式,会有层次结构OutputFormat xmlFormat = OutputFormat.createPrettyPrint();// 没有层次结构,所有节点都在一行
//            OutputFormat compactFormat = OutputFormat.createCompactFormat();//设置文件编码xmlFormat.setEncoding("UTF-8");// 设置换行
//            xmlFormat.setNewlines(true);// 生成缩进
//            xmlFormat.setIndent(true);// 使用4个空格进行缩进, 可以兼容文本编辑器xmlFormat.setIndent("    ");//创建写文件方法XMLWriter xmlWriter = new XMLWriter(new FileWriter("language.xml"),xmlFormat);//写入文件xmlWriter.write(document);//关闭xmlWriter.close();
} catch (Exception e) {e.printStackTrace();
}

SAX方式解析xml

此方式只适合获取节点信息,不适合修改xml文件
book实体类

package com.webservice;
/*** @author :li* @date :Created in 2020/12/12 21:34* @description:book实体类* @modified By:* @version: $*/
public class Book {private String title;private String author;private Double price;public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}@Overridepublic String toString() {return "Book{" +"title='" + title + '\'' +", author='" + author + '\'' +", price=" + price +'}';}
}

book.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<books><book><title>java基础</title><author>张三</author><price>45</price></book><book><title>C语言</title><author>李四</author><price>33</price></book>
</books>

MySaxHandler解析类

package com.webservice;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;import java.util.ArrayList;
import java.util.List;
/*** @author :li* @date :Created in 2020/12/12 21:24* @description:SAX解析器* @modified By:* @version: $*/
public class MySaxHandler extends DefaultHandler {private List<Book> list = new ArrayList<>();private String nodeName;private Book book;public List<Book> getList() {return list;}public void setList(List<Book> list) {this.list = list;}@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {super.characters(ch, start, length);
//        System.out.println("characters");String text = new String(ch, start, length);if ("title".equals(nodeName)){book.setTitle(text);}else if ("author".equals(nodeName)){book.setAuthor(text);}else if ("price".equals(nodeName)){book.setPrice(Double.parseDouble(text));}}@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {super.endElement(uri, localName, qName);
//        System.out.println("endElement");if (qName.equals("book")){list.add(book);}/*** 此处要设置为空,否则当节点为price时,会调用characters()方法,此时得到的文本内容会是空,而* 执行Double.parseDouble(text)回报错*/nodeName = "";}@Overridepublic void endDocument() throws SAXException {super.endDocument();
//        System.out.println("endDocument");}@Overridepublic void startDocument() throws SAXException {super.startDocument();
//        System.out.println("startDocument");}/**** @param uri 节点的命名空间 ,对命名空间的详细介绍https://www.runoob.com/xml/xml-namespaces.html* @param localName* @param qName 节点名称* @param attributes 属性实体类* @throws SAXException*/@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {super.startElement(uri, localName, qName, attributes);
//        System.out.println("startElement");System.out.println("uri:" + uri + "===" + "localname:" + localName);this.nodeName = qName;Book book = null;if (qName.equals("book")){book = new Book();this.book = book;}}
}

测试类

package com.webservice;import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;
import java.util.List;
/*** @author :li* @date :Created in 2020/12/12 18:44* @description:通过SAX解析xml文档* @modified By:* @version: $*/
public class SAXTest {public static void main(String[] args) {SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();try {/*** 通过打印发现规律* 1、重写方法是按照startDocument、startElement、characters、endElement、endDocument执行的,*    且执行完所有节点的startElement后才开始执行endElement;* 2、每次执行startElement和endElement后就执行characters方法* 3、重写的方法的参数都是初始化好的*/InputStream resourceAsStream = SAXTest.class.getClassLoader().getResourceAsStream("book.xml");SAXParser saxParser = saxParserFactory.newSAXParser();MySaxHandler mySaxHandler = new MySaxHandler();saxParser.parse(resourceAsStream,mySaxHandler);// 获取解析到的数据List<Book> bookList = mySaxHandler.getList();for (Book book : bookList) {System.out.println("book====" + book );}} catch (ParserConfigurationException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}
}

java处理解析xml文件的几种方法及每种方法的区别相关推荐

  1. Java 实现解析xml文件的基本步骤(做笔记)

    今天,初步学习了Java实现解析xml文件的基本步骤.不多说先上图解了. 源代码: public class Dome1 { public static void main(String[] args ...

  2. Java jdom解析xml文件带冒号的属性

    Java jdom解析xml文件带冒号的属性 转载请标明出处: https://dujinyang.blog.csdn.net/article/details/99644824 本文出自:[奥特曼超人 ...

  3. Java - DOM4J解析XML文件

    文章目录 1. XML文档说明 2. XML解析 2.1 常见的解析方式 2.2 DOM4J解析xml 2.3 XPath表达式解析XML 3. 解析XML并封装到类中 4. 参考资料 1. XML文 ...

  4. JAVA SAX解析XML文件

    [代码] [Java]代码 view sourceprint? 001 package SAXparse; 002 003 004 import java.io.FileInputStream; 00 ...

  5. java jdom解析xml文件_Java 使用JDOM解析XML文档

    使用JDOM解析XML文档 JDOM是一种使用 XML(标准通用标记语言下的一个子集) 的独特 Java 工具包.下面我们来看一下怎么使用 JDOM来解析XML文档. 首先下载JDOM的jar包,并导 ...

  6. Java中解析XML文件之SAX方式

    1.SAX解析方式,是将XML文件逐行读进内存进行解析的. 2.首先编写一个SAXHandler(SAX处理类),这个类需要继承DefaultHandler类 3.在SAXHandler类中需要重写s ...

  7. java xsd 解析 xml文件_Java针对XSD文件验证XML文件的最佳方法是什么?

    小编典典 Java运行时库支持验证.上次我检查的是幕后的Apache Xerces解析器.你可能应该使用javax.xml.validation.Validator. import javax.xml ...

  8. java xsd 解析 xml文件_xsd解析xml

    下面讲述根据xml生成对应序列化反序列化类的过程,xml需要首先转化为xsd,然后再生成为实体类.其中,XSD是XML Schema Definition的缩写. 1.拥有一个xml文件 2.打开vs ...

  9. Java中DOM4J解析xml文件浅析

      DOM4J解析它是JDOM的一种智能分支.它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持.XML Schema支持以及用于大文档或流化文档的基于事件的处理.它还提供了构建文档表 ...

最新文章

  1. HDU 3973 AC's String 字符串哈希
  2. Python基础——PyCharm版本——第四章、基础语法-分支语句(条件判断if语句)
  3. JavaScript的值传递和引用传递
  4. python if elif else_Python3使用独立的if语句与使用if-elif-else结构的不同之处
  5. 有关为旧版代码创建存根的更多信息–测试技术7
  6. fatfs文件系统f_lseek追加文件
  7. ggradar画雷达图
  8. Windows下部署ubuntu16.04+anaconda2.7+tensorflow
  9. Facade in Java
  10. 通过SecureCRT打开HCL模拟器命令行
  11. vue滚动条插件vue-happy-scroll
  12. 一文搞懂C语言如何用指针来代替变量和数组进行数据的存储
  13. 大数据知识梳理(Hadoop、HDFS)(整理中。。。)
  14. 元音上师海口开示观心
  15. iOS逆向小知识: Cycript Tricks Powerful private methods
  16. 评测三款免费的azw3阅读器(windows适用)
  17. 擎创动态 | 官宣!与深智城集团正式签约
  18. monodepth2 理解
  19. python将签名自动插入到PDF文件(PyPDF2)
  20. 计算机虚拟仪器技术文献,文献翻译-基于虚拟仪器技术的温度测控系统设计.doc...

热门文章

  1. 公众号可改20个字 微信公众号改错字功能升级
  2. Android开发之用户头像上传
  3. C语言数组 :用户输入一个数, 我要用这个数当数组的长度。怎么办呢
  4. Spring之DI注入方式
  5. python win32gui+pynput 自动回复qq消息
  6. MySQL连接错误实例
  7. IOMMU/SMMUV3代码分析(1)SMMU设备的分配
  8. mysql记录锁、间隙锁、临键锁
  9. 国际短信平台接口调用的方法步骤,简单5步快速教程
  10. 企业微信如何退出之前的公司