XML:
01.可扩展标记语言
02.符合w3c标准(w3c:万维网联盟组织!规定xml,HTML,css,js,数据库......一系列的规范)
03.着重数据的保存,不专注显示!
04.无需预编译
以xml作为后缀名的文件,我们称之为xml文件!
例:学生信息.xml
<?xml version="1.0" encoding="gbk"?> <school> <class location="一楼" name="一班"> <student name="一班小黑" age="7"/> <student name="一班小白" age="5">有点悲哀</student> </class> <class location="二楼" name="二班"> <student name="二班小黑" age="7">有点可爱</student> <student name="二班小白" age="5"/> </class> <class location="三楼" name="三班"> <student name="三班小黑" age="7">有点调皮</student> <student name="三班小白" age="5"/> </class> </school>
注意点:
01.根节点只能有一个
02.所有节点都是成对出现的
<学校>开放标签
</学校>闭合标签
03.所有的节点必须正确的嵌套
04.xml文件中严格区分大小写
XML的节点结构,我们称之为dom树!==》因为整个xml文件的节点结构像一个倒挂的树!
DOM:(Document Object Model)文档对象模型
XML文档中特殊字符的转换:
> >
< <
' '
" "
& &
空格
DTD文件(Document Type Definition): 针对xml文件的约束文件!
<!ELEMENT struts ((package|include|bean|constant)*, unknown-handler-stack?)> <!ATTLIST struts order CDATA #IMPLIED > <!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)> <!ATTLIST package name CDATA #REQUIRED extends CDATA #IMPLIED namespace CDATA #IMPLIED abstract CDATA #IMPLIED strict-method-invocation CDATA #IMPLIED externalReferenceResolver NMTOKEN #IMPLIED >
01.<!ELEMENT struts ((package|include|bean|constant)*, unknown-handler-stack?)>
ELEMENT===》元素 package (内容)===》子元素
02.<!ELEMENT package (result-types?, interceptors+, action*)>
result-types的位置 > nterceptors的位置 > action的位置
? :子元素至少出现0次,最多出现1次!
+ :子元素至少出现1次
* :子元素至少出现0次,最多出现N次!
03.<!ATTLIST package
name CDATA #REQUIRED
extends PCDATA #IMPLIED
>
ATTLIST:package元素中可以包含的属性
name,extends : 属性名
CDATA : Character Data 字符数据==》解析器不会解析的文本
PCDATA: Parsed Character Data 被解析的字符数据==》解析器会解析的文本
#REQUIRED :属性是必须有的
#IMPLIED :属性不是必须的
Schema 可以替换 DTD, 文件的扩展名是 xsd (XML Schema Definition)
解析xml文件:
1.DOM:基于xml文档树结构的解析,把文件中的内容全部读到内存中,占内从,消耗资源多!
2.SAX:基于事件的解析,不会把文件中的内容全部读到内存中,占用资源少!
3.JDOM:针对于java的特定模型!满足2 8 原则!自身没有解析器,依赖于SAX2的解析器
4.DOM4J: 是JDOM一个分支,开放源码,性能优异,功能强大!依赖于SAX的解析器
public class SchoolDemo { static Scanner input=new Scanner(System.in); static Document document=null;//dom树 static Element root=null; public static void main(String[] args) { System.out.println("**************进入解析xml文件世界**************"); System.out.println("==========1.新增节点==========="); System.out.println("==========2.删除节点==========="); System.out.println("==========3.修改节点==========="); System.out.println("==========4.查询节点==========="); System.out.println("请输入您的选择:"); int choose=input.nextInt(); /** * 不管你进行什么操作,前提得有 指定xml文件的dom树 * 学校信息.xml 我们需要解析的xml文件 */ String file="学校信息.xml"; getDocment(file); switch(choose){ case 1://新增节点 addClass(file); break; case 2://删除节点 deleteClass(file); break; case 3://修改节点 updateClass(file); break; case 4://查询节点 getAllClass(file); break; } } /** * 查询节点 */ private static void getAllClass(String file) { //根据根节点获取school获取所有的class子节点集合 Iterator <Element> classes = root.elementIterator(); while(classes.hasNext()){ Element clazz = classes.next(); System.out.println("班级名称"+clazz.attributeValue("name")); System.out.println("班级位置"+clazz.attributeValue("location")); //根据class节点获取所有的student子节点集合 Iterator <Element> students = clazz.elementIterator(); while(students.hasNext()){ Element student = students.next(); System.out.println("学生姓名:"+student.attributeValue("name")); System.out.println("学生年龄:"+student.attributeValue("age")); if(!student.getTextTrim().equals("")){ System.out.println("这个学生的描述信息是"+student.getTextTrim()); } } } } /** * 修改节点 * @param file */ private static void updateClass(String file) { System.out.println("请您输入需要修改的class名称:"); String className=input.next(); System.out.println("请输入新的class名称:"); String newclassNmae=input.next(); //从根节点获取所有子节点 Iterator <Element> classes = root.elementIterator(); while(classes.hasNext()){ Element clazz = classes.next(); if(clazz.attributeValue("location").equals(className)){ clazz.setAttributeValue("location", newclassNmae); } } if(saveXML(file)){ System.out.println("修改成功"); }else{ System.out.println("修改失败"); } } /** * 删除节点 */ private static void deleteClass(String file) { System.out.println("请输入需要删除的节点名称:"); String className=input.next(); //从根节点中获取所有的子节点 Iterator <Element> classes = root.elementIterator(); while(classes.hasNext()){ Element clazz = classes.next();//获取具体的一个子元素class if(clazz.attributeValue("name").equals(className)){ //删除节点 不允许自杀 必须通过父级节点删除 classes.remove(); } } if(saveXML(file)){ System.out.println("删除成功"); }else{ System.out.println("删除失败"); } } /** * 新增节点 * @param file */ private static void addClass(String file) { //在根节点下创建一个新节点 Element classElement = root.addElement("class"); //给class节点新增属性 classElement.addAttribute("name", "四班"); classElement.addAttribute("location", "四楼"); //再次增加子节点student Element studentElement = classElement.addElement("student"); //给student节点增加属性 studentElement.addAttribute("name", "四班小黑"); studentElement.addAttribute("age", "13"); /** * 以上的操作相当于在内存中创建了如下内容 * <class name="四班" location="四楼"> * <student name="四班小黑" age="13"></student> *</class> * *再次强调是在内存中!!还没有真正的保存在xml文件中; * */ if(saveXML(file)){ System.out.println("新增成功"); }else{ System.out.println("新增失败"); } } /** * 把内存中的数据 真正的保存在xml文件中====》数据的持久化 * @param file 需要持久化的文件 * @return */ private static boolean saveXML(String file) { XMLWriter writer=null;//创建输出流对象 OutputFormat format=null; //创建输出流格式化对象 format=OutputFormat.createPrettyPrint(); format.setEncoding("gbk");//设置编码格式 try { writer=new XMLWriter(new FileWriter(file),format); //真正的把dom树写入xml文件中 writer.write(document); } catch (IOException e) { e.printStackTrace(); return false; }finally{//关闭输出流 try { writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return true; } /** * 目的:获取dom树 * 需要 解析的xml文件 */ private static void getDocment(String file) { SAXReader reader=new SAXReader();//创建解析器对象 try { document = reader.read(file);//获取dom树 root=document.getRootElement();//获取根节点 } catch (DocumentException e) { e.printStackTrace(); } } }