4. jaxp----dom解析器(DocumentBuilderFactory、DocumentBuilder)
1.DocumentBuilderFactory--解析器工厂(抽象类 javax.xml.parsers.DocumentBuilderFactory)
newInstance() 获取 DocumentBuilderFactory 的新实例。
newDocumentBuilder() 使用当前配置的参数创建一个新的 DocumentBuilder 实例。
2.DocumentBuilder--解析器(抽象类 javax.xml.parsers.DocumentBuilder)
parse(String uri)
将给定 URI 的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。(url是相对路径---项目)
- Document (接口,父接口Node org.w3c.dom.Document)
- Node (接口 org.w3c.dom.Node )
3.Document(接口,父接口Node org.w3c.dom.Document)
getElementsByTagName(String tagname)
返回文档中所有指定的标签名节点(NodeList)
getElementById(String elementId)
返回具有带给定值的 ID 属性的 Element。
createElement(String tagName)
创建指定的节点(标签)。
createTextNode(String data)
创建给定指定字符串的 Text 节点。
4.NodeList(接口)
jdk文档介绍:NodeList 接口提供对节点的有序集合的抽象,没有定义或约束如何实现此集合。DOM 中的 NodeList 对象是活动的
getLength() 列表中的节点数。
item(int index) 返回集合中的第 index 个项(Node类型)。
5.Node(接口 org.w3c.dom.Node )常用方法
- 获取
getFirstChild() 此节点的第一个子节点。
getLastChild() 此节点的最后一个节点。
getParentNode() 此节点的父节点。
getChildNodes() 包含此节点的所有子节点的 NodeList。
getNextSibling() 直接在此节点之后的节点。
getNodeValue() 此节点的值,取决于其类型;
getPreviousSibling() 直接在此节点之前的节点。
getTextContent() 此属性返回此节点及其后代的文本内容。
- 添加
appendChild(Node newChild) 将节点 newChild 添加到此节点的子节点列表的末尾。
insertBefore(Node newChild, Node refChild) 在现有子节点 refChild 之前插入节点 newChild。
- 删除
removeChild(Node oldChild) 从子节点列表中移除 oldChild 所指示的子节点,并将其返回。
- 修改
replaceChild(Node newChild, Node oldChild) 将子节点列表中的子节点 oldChild 替换为 newChild,并返回 oldChild 节点。
setNodeValue(String nodeValue) 此节点的值,取决于其类型;
setTextContent(String textContent) 此属性返回此节点及其后代的文本内容。
- 判断
isEqualNode(Node arg) 测试两个节点是否相等
xml文件
<?xml version="1.0" encoding="uft-8"?> <!DOCTYPE persion SYSTEM "NewFile1.dtd"> <persion ID="persion"> <name ID="name1">张三</name> <name ID="name2">zhangsan</name> <age ID="age">18</age> <sex ID="sex">男</sex> </persion>
java代码(根据标签名,查询标签里面的文本)
public class Demo1 { public static void main(String[] args) throws Exception { //查询标签名为name中的文本 selText("name"); } //查询 public static void selText(String strname) throws ParserConfigurationException, SAXException, IOException { //实例化解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //根据解析器工厂实例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //获取xml的全部节点(根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象) Document document = builder.parse("src/NewFile1.xml"); //根据标签名获取 NodeList list = document.getElementsByTagName(strname); for(int i = 0 ; i<list.getLength() ; i++) { //获取每一个name节点 Node name = list.item(i); //获取每个name节点里面的文本 String nametext = name.getTextContent(); //输出文本 System.out.println(nametext); } } }
结果
在我们使用增删改的时候,我们改动的都是内存中的数据节点,想要改动硬盘上面的数据节点,我们需要更新xml文本,下面是更新文本的一些类和方法
注意:我们的格式要是utf-8,不然我们更新后中文会出现乱码的哦!(gbk和utf-16不能写)
TransformerFactory(抽象类 javax.xml.transform ,TransformerFactory 实例可用于创建 Transformer
和 Templates
对象)
一些方法
newInstance() 创建TransformerFactory实例
newTransformer() 创建Transformer实例
Transformer(抽象类,此抽象类的实例能够将源树转换为结果树。javax.xml.transform)
transform(Source xmlSource, Result outputTarget) 将 XML Source
转换为 Result
。
例如:transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml"));
- Source 接口 实现类之一 DOMSource
- Result 接口 实现类之一 StreamResult
添加节点(标签):在最后一个name标签里面添加新标签
代码如下:
public class Demo2 { public static void main(String[] args) throws Exception { //实例化解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //实例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //获取整个文档的节点对象 Document document = builder.parse("src/NewFile1.xml"); //创建一个标签 Element newelement = document.createElement("newelement"); //创建文本 Text text = document.createTextNode("新添加的标签"); //把文本添加到新创建的标签里面 newelement.appendChild(text); //获取所有的name标签 NodeList list = document.getElementsByTagName("name"); //获取最后一个name标签 Node node = list.item(list.getLength()-1); //在最后一个name标签里面添加一个子标签(newelement) node.appendChild(newelement); //因为我们处理的都是内存中的数据,不会影响到硬盘上面的数据,所以我们要把我们处理后的数据重新存储到硬盘上。 //更新xml文件(增删改都需要更新xml文件) TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml")); } }
xml更新后(我们可以发现添加成功了,但是格式看着很不爽)
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion"> <name ID="name1">张三</name> <name ID="name2">zhangsan<newelement>新添加的标签</newelement></name> <age ID="age">18</age> <sex ID="sex">男</sex> </persion>
删除节点:删除上面添加的标签(下面这个方法只能删除一个目标文件)
public class Demo3 { public static void main(String[] args) throws Exception { //实例化解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //实例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //获取xml文档(根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象) Document document = builder.parse("src/NewFile1.xml"); //获取全部的目标节点对象(标签) NodeList list = document.getElementsByTagName("newelement"); //获取NodeList集合中的一个目标节点 Node node = list.item(0); //获取目标节点的父节点 Node faterNode = node.getParentNode(); //根据父节点删除父节点中的子节点(目标节点),如果要一次删除多个,那么需要使用循环 faterNode.removeChild(node); //更新xml文档 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml")); } }
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion"> <name ID="name1">张三</name> <name ID="name2">zhangsan</name> <age ID="age">18</age> <sex ID="sex">男</sex> </persion>
修改:把标签名为sex的里面的文本修改
public class Demo4 { public static void main(String[] args) throws Exception { //实例化解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //实例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //获取整个文档的节点对象 Document document = builder.parse("src/NewFile1.xml"); //获取要修改的全部节点(NodeList集合) NodeList list = document.getElementsByTagName("sex"); //获取目标节点的父节点 //循环NodeList集合,修改指定的全部目标节点(标签)中的文本 for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); node.setTextContent("女"); } //更新xml文档 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml")); } }
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion"> <name ID="name1">张三</name> <name ID="name2">zhangsan</name> <age ID="age">18</age> <sex ID="sex">女</sex> </persion>