• JAVA与DOM解析器基础 学习笔记


    要求

      • 必备知识

        JAVA基础知识。XML基础知识。

      • 开发环境

        MyEclipse10

      • 资料下载

        源码下载

     

    文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。各种语言可以按照DOM规范给出解析XML文件的解析器。Sun公司发布的JDK1.4的后续版本中提供了解析XML文件的网API(Java API for XML Processing)。关于XML语法请参考这里。为什么没有对java类和实际对象没做详细说明,我已经到代码中写了注释了,到这里就不做过多的说明了。

    检测命名空间:TestNameSpace.java

    import java.io.File;
    import java.io.IOException;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    
    /**
     * 检查命xml标记的命名空间
     * @author licheng
     *
     */
    public class TestNameSpace {
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            SAXParserFactory factory=SAXParserFactory.newInstance(); //语法解析器的工厂对象
            factory.setNamespaceAware(true); //允许使用命名空间
            try {
                SAXParser saxParser=factory.newSAXParser();  //获取语法解析器
                MyHeader handle=new MyHeader(); //创建输出句柄
                saxParser.parse(new File("student.xml"), handle); //开始语法解析   文件放到项目根目录不是WebRoot
            }  catch (Exception e) {  //抛出异常
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    
    /**
     * 创建输出句柄对象
     * @author Administrator
     *
     */
    class MyHeader extends DefaultHandler{
        @Override //覆盖父类的方法
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            if(uri.length()>0) 
                System.out.println("标记:"+localName+"的命名空间是:"+uri);
            else
                System.out.println("标记:"+localName+"没有命名空间");
        }
    }

    浏览器中的DOM解析器只检测XML文件是否是规范的,而不能检测XML文件的有效性,此时我们可以使用JAVA提供的DOM解析器来检查一个XML文件的有效性:

    TestValidate.java

    import java.io.File;
    import java.io.IOException;
    import java.util.Scanner;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    
    import org.w3c.dom.Document;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
    import org.xml.sax.helpers.DefaultHandler;
    
    /**
     * 检查XML文件的有效性
     * 浏览器中的XML解析器只检查XML文件是否是规范的,并不检查XML文件是否遵守DTD规定的约束条件。
     * 此时就可以使用DOM解析器来检查一个XML文件是否是有效的。
     * @author licheng
     *
     */
    public class TestValidate {
    
        
        public static void main(String[] args) {
            String fileName=null;
            Scanner reader=new Scanner(System.in);  
            System.out.print("请输入要验证有效性的XML的文件:");
            fileName=reader.nextLine();  //从控制台读取一行数据
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();  //DocumentBuilderFactory工厂对象 获取自身实例 
            factory.setValidating(true);  //设置有效性检测为真
            try {
                DocumentBuilder builer=factory.newDocumentBuilder();//获取DOM解析器
                MyHandler handler=new MyHandler(); //创建MyHandler实例
                builer.setErrorHandler(handler); // 设置解析器的错误句柄为 MyHandler的实例
                Document document=builer.parse(new File(fileName)); //DOM解析器解析 XML文件
                if(handler.errorMessage==null){   //判断handler对象是否含有错误信息
                     System.out.print(fileName+"文件是效的");
                }else{
                    System.out.print(fileName+"文件是无效的");
                }
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    
    }
    
    /**
     * 创建输出句柄
     * @author Administrator
     *
     */
    class MyHandler extends DefaultHandler{
    
        String errorMessage=null;
        /**
         * 一般性错误
         */
        public void error(SAXParseException e) throws SAXException {
            errorMessage=e.getMessage();
            System.out.print("一般错误:"+ errorMessage);
        }
    
        /*
         * 
         * 致命错误 程序终止
         */
        public void fatalError(SAXParseException e) throws SAXException {
            errorMessage=e.getMessage();
            System.out.print("致命错误:"+ errorMessage);
        }
        
        
    }

    获取XML声明信息,根节点名称,指定节点的信息:JAXPOne.java

    import java.io.File;
    import java.io.IOException;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.SAXException;
    
    
    /**
     * JAVA DOM解析器入门   
     * 输出书籍信息
     * @author licheng
     *
     */
    public class JAXPOne {
    
        
        public static void main(String[] args) {
            // DocumentBuilderFactory对象调用newInstance方法实例化一个DocumentBuilderFactory对象
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            try {
                //factory对象调用newDocumentBuilder创建 domParser DOM解析器
                DocumentBuilder domParser=factory.newDocumentBuilder();
                try {
                    
                    Document document=domParser.parse(new File("student.xml"));
                    String version=document.getXmlVersion();  //获取XML版本号
                    System.out.println("version:"+version);
                    
                    String encoding=document.getXmlEncoding(); //获取声明编码
                    System.out.println("encoding:"+encoding);
                    
                    Element root=document.getDocumentElement(); //获取根节点 是先要获取根节点吗
                    String rootName=root.getNodeName(); //获取节点的名称
                    System.out.println("rootName:"+rootName);
                    System.out.println(rootName+"类型为:"+root.getNodeType()); //获取节点类型 dom的级别
                    
                    NodeList nodelist=root.getElementsByTagName("book"); //获取节点列表
                    int size=nodelist.getLength();
                    for(int k=0;k<size;k++){
                        Node node=nodelist.item(k); //获取节点
                        String name=node.getNodeName(); //节点名称
                        String content=node.getTextContent(); //获取内容  包含子孙节点中的文本数据
                        System.out.println(name+":"+content);
                        //System.out.println(name+"节点类型:"+node.getNodeType()); //获取节点类型 dom的级别
                    }
                    
                } catch (SAXException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }

    使用递归方法输出节点中的数据:JAXPTwo.java

    import java.io.File;
    import java.io.IOException;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.Text;
    import org.xml.sax.SAXException;
    
    
    /**
     * 递归方法输出节点中的数据
     * @author licheng
     *
     */
    public class JAXPTwo {
    
        /**
         *主函数
         */
        public static void main(String[] args) {
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            try {
                DocumentBuilder domParser=factory.newDocumentBuilder();
            
                Document document=domParser.parse(new File("bookinfo.xml"));
                NodeList nodeList=document.getChildNodes();
                output(nodeList);
            } catch (Exception e) {
                e.printStackTrace();
            }
            
    
        }
        
        
        /**
         * 递归输出节点数据
         * @param nodelist 节点列表
         */
        public static  void output(NodeList nodelist){
            int size=nodelist.getLength();  //获取接点列表的长度
            for(int k=0;k<size;k++){
                Node node=nodelist.item(k); //获取节点列表中的一项 
                if(node.getNodeType()==node.TEXT_NODE){ //节点类型为TEXT
                    Text textNode=(Text)node;
                    String content=textNode.getWholeText();
                    System.out.print(content);
                }
                if(node.getNodeType()==Node.ELEMENT_NODE){ //节点类型为ELEMENT
                    Element elementNode=(Element)node;
                    String name=elementNode.getNodeName();
                    System.out.print(name);
                    NodeList nodes=elementNode.getChildNodes();
                    output(nodes);  //递归掉用该方法
                }
            }
            
        }
    
    }

    输出Text节点信息,统计一共有多少个Text文本节点:JAXPText.java

    import java.io.File;
    import java.io.IOException;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.Text;
    import org.xml.sax.SAXException;
    
    
    /**
     * 统计一共有多少个Text节点
     * @author licheng
     *
     */
    public class JAXPText {
    
        /**
         *主函数
         */
        public static void main(String[] args) {
            GiveData give=new GiveData();
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            try {
                DocumentBuilder domParser=factory.newDocumentBuilder();
                
                Document document=domParser.parse(new File("bookinfo.xml"));
                NodeList nodeList=document.getChildNodes();
                give.output(nodeList);
                System.out.println("一共有"+give.m+"个Text节点");
            } catch (Exception e) {
                e.printStackTrace();
            }
            
    
        }
        
    }
    
    class GiveData{
        int m=0; //text的个数
        public   void output(NodeList nodelist){
            int size=nodelist.getLength();  //获取接点列表的长度
            for(int k=0;k<size;k++){
                Node node=nodelist.item(k); //获取节点列表中的一项 
                if(node.getNodeType()==node.TEXT_NODE){ //节点类型为TEXT
                    Text textNode=(Text)node;
                    String content=textNode.getWholeText();
                    m++;
                    System.out.print(content);
                }
                if(node.getNodeType()==Node.ELEMENT_NODE){ //节点类型为ELEMENT
                    Element elementNode=(Element)node;
                    String name=elementNode.getNodeName();
                    System.out.print(name);
                    NodeList nodes=elementNode.getChildNodes();
                    output(nodes);  //递归掉用该方法
                }
            }
            
        }
    }

    获取Attr属性节点信息:JAXPAttr.java

    import java.io.File;
    import java.io.IOException;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    
    import org.w3c.dom.Attr;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NamedNodeMap;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.Text;
    import org.xml.sax.SAXException;
    
    
    /**
     * 遍历属性节点信息
     * @author licheng
     *
     */
    public class JAXPAttr {
    
        /**
         *主函数
         */
        public static void main(String[] args) {
            GiveData3 give=new GiveData3();
            
            try {
                DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
                factory.setIgnoringElementContentWhitespace(true);  //忽略空白缩进
                DocumentBuilder domParser=factory.newDocumentBuilder();
                Document document=domParser.parse(new File("student.xml"));
                Element root=document.getDocumentElement();
                NodeList nodeList=root.getChildNodes();
                give.output(nodeList);
            
            } catch (Exception e) {
                e.printStackTrace();
            }
            
    
        }
        
    }
    
    class GiveData3{
        
        public   void output(NodeList nodelist){
            int size=nodelist.getLength();  //获取接点列表的长度
            for(int k=0;k<size;k++){
                Node node=nodelist.item(k); //获取节点列表中的一项 
                if(node.getNodeType()==node.TEXT_NODE){ //节点类型为TEXT
                    Text textNode=(Text)node;
                    String content=textNode.getWholeText();
                    System.out.print(content);
                }
                if(node.getNodeType()==Node.ELEMENT_NODE){ //节点类型为ELEMENT
                    Element elementNode=(Element)node;
                    String name=elementNode.getNodeName();
                    System.out.print(name);
                    NamedNodeMap map=elementNode.getAttributes(); //获取属性节点集合
                    /**
                     * 属性节点操作
                     */
                    for(int m=0;m<map.getLength();m++){
                        Attr attrNode=(Attr)map.item(m);
                        String attrName=attrNode.getName(); //属性名称
                        String attrValue=attrNode.getValue(); //属性值
                        System.out.print(" "+attrName+"="+attrValue);
                    }
                    NodeList nodes=elementNode.getChildNodes();
                    output(nodes);  //递归掉用该方法
                }
            }
            
        }
    }

    忽略文本空白:JAXPEight.java

    import java.io.IOException;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.Text;
    import org.xml.sax.SAXException;
    
    
    
    
    public class JAXPEight {
    
    
        public static void main(String[] args) {
            GiveD give=new GiveD();
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            factory.setIgnoringElementContentWhitespace(true); //这个确实是可行的吗??
            try {
                DocumentBuilder domPaser=factory.newDocumentBuilder();
                Document document=domPaser.parse("student.xml");
                Element root=document.getDocumentElement();
                NodeList nodeList=root.getChildNodes();
                
                give.output(nodeList);
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    
    
    class GiveD{
        int m=0;
        public void output(NodeList nodeList){
            int size=nodeList.getLength();
            for(int k=0;k<size;k++){
                Node node=nodeList.item(k);
                if(node.getNodeType()==Node.TEXT_NODE){
                    Text textNode=(Text)node;
                    String content=textNode.getWholeText();
                    m++;
                    System.out.print(content);
                }
                if(node.getNodeType()==Node.ELEMENT_NODE){
                    Element elementNode=(Element)node;
                    String name=elementNode.getNodeName();
                    System.out.print(" ");
                    NodeList nodes=elementNode.getChildNodes();
                    output(nodes);
                }
            }
        }
        
    }

    [使用DOM生成XML文件]此类通过已经存在的文件 获取Document对象 修改DOM后 创建XML文件:JAXPTransformer.java

    import java.io.File;
    import java.io.FileOutputStream;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    
    /**
     * 通过已经存在的文件 获取Document对象
     * 修改DOM后
     * DOM创建XML文件
     * @author licheng
     *
     */
    public class JAXPTransformer {
        public static void main(String[] args) {
            
            ModifyNode modify=new ModifyNode();
            try {
                DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
                factory.setIgnoringElementContentWhitespace(true);  //忽略空白缩进
                DocumentBuilder domParser=factory.newDocumentBuilder();
                Document document=domParser.parse(new File("mobileNumber.xml")); //通过已经存在的文件创建Document对象
                Element root=document.getDocumentElement();
                NodeList nodeList=root.getChildNodes();
                modify.modifyNode(nodeList, document); //调用修改DOM的方法
                TransformerFactory transFactory=TransformerFactory.newInstance(); //工厂对象获取transFactory实例
                Transformer transformer=transFactory.newTransformer(); //获取Transformer实例
                DOMSource domSource=new DOMSource(document);
                File file=new File("newXML.xml");
                FileOutputStream out=new FileOutputStream(file);
                StreamResult xmlResult=new StreamResult(out);
                transformer.transform(domSource, xmlResult);
            
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            
    
        }
    }
    class ModifyNode{
        int m=0;
        Document document;
        public  void modifyNode(NodeList nodeList,Document document){
            this.document=document;
            int size=nodeList.getLength();
            for(int k=0;k<size;k++){
                Node node=nodeList.item(k);
                if(node.getNodeType()==Node.ELEMENT_NODE){
                    Element elementNode=(Element)node;  //这里获取节点
                    String name=elementNode.getNodeName();//节点名称
                    if(name.equals("用户")){ //节点判断
                        m++;
                        Node textN=document.createTextNode("80元"); //创建文本节点
                        Node elementN=document.createElement("月租费"); //穿件节点
                        elementN.appendChild(textN);
                        elementNode.appendChild(elementN);
                    }
                    NodeList nodes=elementNode.getChildNodes();
                    modifyNode(nodes, document); //此处递归
                }
            }
            
        }
        
        
        
        
        
        
        
    }

    [使用DOM生成XML文件]上例中通过已有的XML文件产生一个Document对象,而本例直接 调用 newDocument()方法获取对象。

    JAXPTransformer2.java

    import java.io.File;
    import java.io.FileOutputStream;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    
    /**
     * domPaser 调用 newDocument() 方法获取Document对象
     * 然后为Document节点添加子孙节点
     * 使用Transformer生成一个新的XML文件
     * @author licheng
     *
     */
    public class JAXPTransformer2 {
        public static void main(String[] args) {
            try {
                String[] personName={"张三","李四","王五"};
                String[] phoneNumber={"123","456","789"};
                DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
                factory.setIgnoringElementContentWhitespace(true);  //忽略空白缩进
                DocumentBuilder domParser=factory.newDocumentBuilder();
                Document document=domParser.newDocument(); //通过调用newDocument() 方法获取实例
                document.setXmlVersion("1.0"); //设置 xml版本号
                Element root=document.createElement("手机用户表");
                document.appendChild(root); //添加根节点
                for(int k=1;k<=personName.length;k++){
                    Node node=document.createElement("用户"); //添加多个用户节点
                    root.appendChild(node);
                }
                NodeList nodeList=document.getElementsByTagName("用户");
                int size=nodeList.getLength();
                for(int k=0;k<size;k++){
                    Node node=nodeList.item(k);
                    if(node.getNodeType()==Node.ELEMENT_NODE){ 
                        Element elementNode=(Element)node; //有必要创建此对象吗???
                        Node nodeName=document.createElement("姓名");
                        Node nodeNumber=document.createElement("号码");
                        nodeName.appendChild(document.createTextNode(personName[k]));
                        nodeNumber.appendChild(document.createTextNode(phoneNumber[k]));
                        elementNode.appendChild(nodeName);
                        elementNode.appendChild(nodeNumber);
                    }
                }
                TransformerFactory transFactory=TransformerFactory.newInstance(); //工厂对象获取transFactory实例
                Transformer transformer=transFactory.newTransformer(); //获取Transformer实例
                DOMSource domSource=new DOMSource(document);
                File file=new File("phone.xml");
                FileOutputStream out=new FileOutputStream(file);
                StreamResult xmlResult=new StreamResult(out);
                transformer.transform(domSource, xmlResult);
                out.close();
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
    
        }
    }
    作者:Li-Cheng
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    JS 数字时钟的代码(摘录,忘了是从哪了)
    数据写入DataTable C# 2005
    C# 进制转化问题测试下再说(网上的直接转化不好用)
    防sql 注入,就是将sql 的执行命令给排除
    今天研究了一下午网站窄屏/宽屏的切换实现
    解决VS2005下中文输入法全角半角混乱的补丁
    一些实用的站长查询工具
    UE(用户体验)无处不在,留心处处皆学问
    添加了方便聚合的链接
    该好好整理一下自己了
  • 原文地址:https://www.cnblogs.com/Li-Cheng/p/3610424.html
Copyright © 2020-2023  润新知