<?xml version="1.0" encoding="UTF-8"?> <!-- xml:是一个可扩展的标记语言 01.很像超文本标记语言(html) 02.xml文件着重保存或者传输数据,不专注显示 03.无需预编译 04.符合w3c标准 < : < > : > " : " ' : ' & : & <![CDATA[代码]]> CDATA: character data 字符数据 不会被解析器解析的文本!在CDATA标签中定义的代码 不会被当作标记! PCDATA: parsed character data 被解析的字符数据 --> <students> <student id="001" name="小黑黑" score=">80">我是小黑黑</student> <student id="002" name="大黑黑" score="<80">我是大黑黑</student> </students> <![CDATA[ "" ;; '' <><>< ]]>
/** 什么是标记??? 计算机所能理解的一种信息符号!我们之前定义的变量,java中的基本数据类型=====理解成标记! xml:是一种可扩展的标记语言! 01.专注于保存数据,传输!不是显示数据! 02.xml文件中的标签没有被定义,我们可以自定义标签名称! <student name="admin"></student> <学生 姓名="小白"></学生> 03.自我描述性 04.符合W3C标准的! Dom: 文档对象模型(Document Object Model):dom把xml文件映射成倒挂的树 解析xml的4中解析器! Dom:基于xml文档树结构的解析!把文件的内容读取到内存中,比较占内存!消耗资源 SAX:基于事件的解析!不需要将数据存储在内存中!占用资源少! JDom:第一个java特定模型! 2 8原则!本身不包含解析器!使用SAX2解析器来解析xml文件! Dom4j:是Jdom的一个分支!分享源代码! 性能优异!功能强大! <student age="50">小黑</student> student:元素名 age:属性名 50:属性值 小黑:元素内容 特殊字符: < < > > & & ' ' " " CDATA:不被xml解析器解析! <![CDATA[内容]]> */
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE school[ //声明这是一个 school类型的文档 <!ELEMENT school(teacher)> //根节点是 school 下面只能有teacher <!ELEMENT teacher(student+)> //teacher可以有至少一个student节点 <!ELEMENT teacher(student*)> //teacher可以有多个,也可以没有 <!ELEMENT teacher(student?)> //teacher可以有1个,也可以没有 <!ATTLIST teacher //定义teacher节点中可以有的属性 ID CDATA #REQUIRED // #REQUIRED 属性值是 必须的 #IMPLIED 属性值不是必须的 EMPTY 空的 name CDATA "false"> ]>
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入外部的dtd文档 --> <!DOCTYPE school SYSTEM"my.dtd">
=====================DOM解析xml文件=================================
<?xml version="1.0" encoding="UTF-8"?> <PhoneInfo> <Brand name="华为"> <Type name="P9"/> </Brand> <Brand name="苹果"> <Type name="Iphone6"/> <Type name="Iphone7"/> </Brand> </PhoneInfo>
public class DomXml { //声明文档树 static Document document=null; /** * 使用Dom解析xml文件 */ public static void main(String[] args) { getDom(); delPhone(); } /** * 获取dom树 */ public static void getDom(){ try { //01.创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //02.创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); //03.指定需要解析的xml文件 获得整个dom树 document = builder.parse("收藏信息.xml"); //04.获取xml文件的根节点 NodeList list = document.getElementsByTagName("Brand"); System.out.println("有几个Brand节点:"+list.getLength()); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); Element element= (Element) node; System.out.println("手机名称===》"+element.getAttribute("name")); //怎么获取手机下面的品牌信息 NodeList cList = element.getChildNodes(); for (int j = 0; j < cList.getLength(); j++) { Node cNode = cList.item(j); //先判断cNode是否是一个元素节点 if (cNode.getNodeType()==Node.ELEMENT_NODE) { Element cElement= (Element) cNode; System.out.println("手机品牌===》"+cElement.getAttribute("name")); } } } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //把内存中的数据 保存在xml中 public static void saveXml() { try { //???怎么把内存中的 节点 保存到xml中 //01.创建转换器工厂 TransformerFactory factory = TransformerFactory.newInstance(); //02.创建转换器对象 Transformer former = factory.newTransformer(); //这是我们输出格式 former.setOutputProperty("indent", "yes"); //03.从内存中 输出到 xml文件 输出流 DOMSource source=new DOMSource(document); StreamResult result=new StreamResult(new OutputStreamWriter (new FileOutputStream("收藏信息.xml"), "utf-8")); former.transform(source, result); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } } /** * 新增手机信息 */ public static void addPhone(){ //在内存中首先 创建我们需要增加的 节点 Element element = document.createElement("Brand"); //增加属性 element.setAttribute("name", "金立"); //再创建一个节点 只有文档树可以创建节点 Element elementType = document.createElement("Type"); elementType.setAttribute("name", "金立555"); //把type节点放入Brand中 element.appendChild(elementType); //获取根节点 document.getElementsByTagName("PhoneInfo").item(0).appendChild(element); //以上的操作 全都是在 内存中! 并没有真正的保存到xml文件中 saveXml(); //shift +alt +M 选中的区域提取成方法 } /** * 修改手机信息 */ public static void updatePhone(){ //获取需要修改的节点 NodeList list = document.getElementsByTagName("Brand"); //循环操作 for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); Element element=(Element) node; if (element.getAttribute("name").equals("金立")) { element.setAttribute("name", "三星"); } } //把内存中修改的数据 保存到xml saveXml(); } /** * 删除指定的手机信息 */ public static void delPhone(){ //获取需要修改的节点 NodeList list = document.getElementsByTagName("Brand"); //循环操作 for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); Element element=(Element) node; if (element.getAttribute("name").equals("三星")) { element.getParentNode().removeChild(element); } } //把内存中删除的数据 保存到xml saveXml(); } }
public class Dom4jTest { // Dom4j解析xml // 因为所有的方法都需要Dom树 static Document document = null; static Element root = null; public static void main(String[] args) { // 获取dom树 getDocument(); // addPhone(); deletePhone(); updatePhone(); showPhone(); } // 解析xml文件 public static void getDocument() { SAXReader reader = new SAXReader(); try { document = reader.read("收藏信息.xml"); root = document.getRootElement();// 获取根节点 } catch (DocumentException e) { e.printStackTrace(); } } /** * 显示所有的手机信息 */ public static void showPhone() { // 遍历所有的节点 Iterator itBrand = root.elementIterator(); while (itBrand.hasNext()) { Element brand = (Element) itBrand.next(); System.out.println("手机的品牌是:" + brand.attributeValue("name")); System.out.println("手机的编号是:" + brand.attributeValue("id")); System.out.println("===========下面是子节点============"); Iterator itType = brand.elementIterator(); while (itType.hasNext()) {// 获取手机型号 Element type = (Element) itType.next(); System.out.println("手机的型号是:" + type.attributeValue("name")); // 输出文本节点的值 if (!type.getText().equals("")) { System.out.println(type.getTextTrim()); } } } } // 保存xml信息 public static void save(String path) { OutputFormat format = null; XMLWriter writer = null; try { // dom4j的转换器 不用使用 new createPrettyPrint底层有 new format = OutputFormat.createPrettyPrint(); // 写入xml文件 writer = new XMLWriter(new FileWriter(path), format); writer.write(document); } catch (IOException e) { e.printStackTrace(); } finally { // 关流 try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } // 新增节点 public static void addPhone() { Element element = root.addElement("Brand"); // 节点设置属性 element.addAttribute("name", "黑莓"); // 节点下面新增子节点 Element type = element.addElement("Type"); type.addAttribute("name", "A1"); // 保存 省略 我们 节点之间的拼接! dom需要拼接 save("收藏信息.xml"); } // 删除 public static void deletePhone() { // 获取所有Brand Iterator brand = root.elementIterator(); while (brand.hasNext()) { Element element = (Element) brand.next(); // 拿到每一个Brand // 获取属性值 判断是不是 要删除的对象 if (element.attributeValue("name").equals("黑莓")) { element.getParent().remove(element); } } save("收藏信息.xml"); } // 修改 public static void updatePhone() { // 获取所有Brand Iterator brand = root.elementIterator(); while (brand.hasNext()) { Element element = (Element) brand.next(); // 拿到每一个Brand // 获取属性值 判断是不是 要修改的对象 if (element.attributeValue("name").equals("哇哈哈")) { element.attribute("name").setValue("哇哈哈哈哈"); } } save("收藏信息.xml"); } }
覆盖xml文件
public class ParseXml { public static void main(String[] args) throws IOException { saveXml("user.xml"); } /** * * @param path 需要覆盖的xml文件 * @throws IOException */ public static void saveXml(String path) throws IOException{ Document document=DocumentHelper.createDocument(); //创建一个dom对象 //给dom增加根节点 Element students = document.addElement("Students"); //在根节点下面增加 子节点 Element student = students.addElement("Student"); //给子节点增加属性 student.addAttribute("name","小黑"); //创建转换器工厂 OutputFormat format = OutputFormat.createPrettyPrint(); //设置编码格式 format.setEncoding("utf-8"); XMLWriter writer=new XMLWriter(new FileWriter(path), format); //写入xml文件 writer.write(document); //关闭流 writer.close(); } }