基础复习8-XML&反射

HTML&XML

Html和XML都属于SGML(标准通用标记语言)语言分支

程序型标记-HTML(HTML5不属于SGML分支)  XHTML

描述型标记-XML-(1998正式形成标准)

两者都由W3C维护

 

XML:Extensiable Markup Language可扩展标记语言,xml只代表数据本身,而不包含任何样式结构的呈现,所以也称之为一种数据描述语言

Xml作用:

1.实现不同平台之间的数据交换(webservice:soap协议)

2.Xml还可以用于一些应用程序的配置文件(框架,tomcat,servlet)

XML文档构成(当前xml标签必须是*.dtd中定义的

一个标准的XML文档由3个部分构成

1.xml指令<?xml version=”1.0” encoding=”utf-8” standalone="yes"?>

2.文档类型定义<!DOCTYPE books SYSTEM “books.dtd” >(表示当前xml标签必须是books.dtd中定义的)

3.文档元素部分

 

 

Xml指令主要描述xml版本(目前为1.0),编码,文档类型定义是否是一个独立文件

文档类型定义(DTD,XSD):规范文档中允许出现的标记,属性,以及标记之间关系

文档的详细构成部分:标签,属性,文本

 

Xml元素:由一对标签以及标签对之间的内容构成

Xml标签:主要包含开始标记以及结束标记

Xml属性:属性通常定义在元素的开始标记中

 

CDATA:元数据

<![CDATA[

    元数据具体内容

]]>

命名空间:namespace,防止标签的命名冲突

 

<h:table xmlns:h="http://www.w3.org/TR/html4/">

<h:tr>

    <h:td>Apples</h:td>

    <h:td>Bananas</h:td>

</h:tr>

</h:table>

 

<f:table xmlns:f="http://www.w3schools.com/furniture">

    <f:name>African Coffee Table</f:name>

    <f:width>80</f:width>

    <f:length>120</f:length>

</f:table>

XML规范

Xml规范相对HTML来说相当严格

1.标记必须成对出现(空标签例外)

2.标签严格区分大小写

3.属性值必须使用双引号包含

4.属性值中不能包含特殊符号(<,&...)

5.xml支持类似html中实体(&lt; &gt; &quot;)

6.注释代码不允许嵌套

7.一个XML文档中有且只有一对根节点

JSON&XML

AJAX:异步的javascript and XML

JSON:是一种轻量级的数据交换格式,实现不同平台之间的数据交换

XML解析

<?xml version="1.0" encoding="utf-8"?>

<books>

   <book no = "0103410">

      <name>还珠格格</name>

      <author>琼瑶</author>

      <publish>XX版社</publish>

      <price>34.5</price>

   </book>

   <book no = "0103411">

      <name>三国演义</name>

      <author>罗贯中</author>

      <publish>XXX出版社</publish>

      <price>34.5</price>

   </book>

   <book no = "0103412">

      <name>红楼梦</name>

      <author>曹雪芹</author>

      <publish>XXXX出版社</publish>

      <price>34.5</price>

   </book>

</books>

 

1.DOM解析(换行标记也算一个节点)

  将需要被解析的文档完整的加载到内存中,解析为一颗倒置的文档树,可以通过解析器任意获取文档树中的节点

  优点:适合解析较小的文档,解析速度快,可以任意搜索节点,并行搜索

  缺点:一次性加载的整个文档,会消耗大量内存,无法解析过大的文件

public class DomParseDemo {

    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {

        //实例化一个解析工厂

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        //获取解析器对象

        DocumentBuilder builder = factory.newDocumentBuilder();

        //解析文件并获取文档对象

        Document document = builder.parse(new File("src/java/userInfo.xml"));

        //根据元素的标签名获取元素并取出匹配第一个元素(根节点)

        Node root = document.getElementsByTagName("users").item(0);

        //获得当前节点下的所有子节点

        NodeList list = root.getChildNodes();

        //跳过0  因为0是空格节点

        for (int i = 0; i < list.getLength(); i++) {

            Node node = list.item(i);

            //判断当前节点名称是否为user

            if ("user".equals(node.getNodeName())){

                //获取节点中的属性节点集合

                NamedNodeMap nnm = node.getAttributes();

                //根据节点名称(属性名)获取节点值(属性值)

                String id = nnm.getNamedItem("id").getNodeValue();

                String type = nnm.getNamedItem("type").getNodeValue();

                System.out.println(id);

                System.out.println(type);



                //继续搜索user下的子节点

                NodeList user_child_list = node.getChildNodes();

                for (int j = 0; j < user_child_list.getLength(); j++){

                    Node child_node = user_child_list.item(j);

                    if (child_node != null)

                    switch (child_node.getNodeName()){

                        case "name":

                            System.out.println("name:"+child_node.getTextContent());

                            break;

                        case "sex":

                            System.out.println("sex:"+child_node.getTextContent());

                            break;

                        case "age":

                            System.out.println("age:"+child_node.getTextContent());

                            break;

                        case "ismarray":

                            System.out.println("ismarray:"+child_node.getTextContent());

                            break;

                        default:

                            break;

                    }

                }

            }

        }

        System.out.println(document.getElementsByTagName("name").getLength());

    }

 }

2.SAX解析

 基于事件驱动的方式以类似流媒体的方式进行解析,在读取到一部分内容之后立即开始解析,直到读取到文档结束标记后停止解析

  优点:适合解析较大的文档,解析效率较快,一边读取一边解析

  缺点:无法任意搜索节点,比较难以实现并行搜索

public class SAXParseDemo extends DefaultHandler {



    public List<Book> books;

    private Book book;

    private String nowTag;

    //文档开始时触发   读到users触发

    @Override

    public void startDocument() throws SAXException {

        books = new ArrayList<Book>();

        System.out.println("开始解析");

    }



    //读取到开始标记时触发  读到每一个节点开头触发

    @Override

    /** uri         命名空间的url地址

     *  localName   不带命名空间前缀的标签名称

     *  qName       带命名空间的标签名

     *  attribute   元素中的属性列表 例如id(只存在于开始节点)

     */

    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {



        System.out.println("读取到开始标记" + qName);

        //记录当前读取到的开始标记

        nowTag = qName;

        //当读取到一个book的开始标记后创建一个book对象

        if ("book".equals(qName)){

            book = new Book();

            book.setNo(attributes.getValue("no"));

        }

    }



    //读取到文本节点时触发   读到文本节点触发,空白节点也是文本节点

    @Override

    public void characters(char[] ch, int start, int length) throws SAXException {

        String value = new String(ch, start, length);

        System.out.println("读取到文本节点" + value);

        switch (nowTag){

            case "name":

                book.setName(value);

                break;

            case "author":

                book.setAuthor(value);

                break;

            case "publish":

                book.setPublish(value);

                break;

            case "price":

                book.setPrice(value);

                break;

            default:

                break;

        }

        nowTag = "";

    }



    //读取到结束时触发    读到这里</>触发

    @Override

    public void endElement(String uri, String localName, String qName) throws SAXException {

        System.out.println("读取到结束标记" + qName);

        if ("book".equals(qName)){

            books.add(book);

            book = null;

        }

    }



    //文档结束时触发    只执行一次

    @Override

    public void endDocument() throws SAXException {

        System.out.println("解析完成");

    }



    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {

        //创建解析工厂

        SAXParserFactory factory = SAXParserFactory.newInstance();

        //生产解析器

        SAXParser parse = factory.newSAXParser();

        //开始解析

        SAXParseDemo spd = new SAXParseDemo();

        parse.parse("src/java/book.xml", spd);



        for (Book book:spd.books) {

            System.out.println(book);

        }

    }

}

 

  1. JDOM解析
public class JDomParseDemo {

    public static void main(String[] args) throws JDOMException, IOException {



        //创建解析器

        SAXBuilder builder = new SAXBuilder();

        //解析指定文档为一个Document对象

        Document document = builder.build(new File("src/java/book.xml"));

        //获取文档的根节点

        Element root = document.getRootElement();

        //获取根节点下的子节点集合

        List<Element> list = root.getChildren("book");

        for (Element e:list) {

            //取出节点中指定属性值

            String no = e.getAttributeValue("no");

            System.out.println(no);

            //获取当前节点下指定名称的单个子节点

            String name = e.getChild("name").getText();

            String author = e.getChild("author").getText();

            String publish = e.getChild("publish").getText();

            String price = e.getChild("price").getText();



            System.out.println(name);

            System.out.println(author);

            System.out.println(publish);

            System.out.println(price);

            System.out.println("==========");

        }

    }

}

 

4.DOM4J解析

public class Dom4JParseDemo {

    public static void main(String[] args) throws DocumentException {

        //创建一个Dom4J解析器

        SAXReader reader = new SAXReader();

        //解析文档

        Document document = reader.read("src/java/book.xml");

        //获取根节点

        Element root = document.getRootElement();

        //获取当前根节点下指定名称的子节点

        List<Element> list = root.elements("book");

        for (Element e:list) {

            //取出节点中指定属性值

            String no = e.attributeValue("no");

            System.out.println(no);

            //获取当前节点下指定名称的单个子节点

            String name = e.element("name").getText();

            String author = e.element("author").getText();

            String publish = e.element("publish").getText();

            String price = e.element("price").getText();



            System.out.println(name);

            System.out.println(author);

            System.out.println(publish);

            System.out.println(price);

            System.out.println("==========");

        }

    }

}

快速搜索节点:

public class Dom4J_XPathDemo {

    public static void main(String[] args) throws DocumentException {

        //获取解析器

        SAXReader reader = new SAXReader();

        //获取文档对象

        Document document = reader.read("src/java/book.xml");



        //快速搜索某节点

        List<Node> list = document.selectNodes("books/book/name");

        for (Node node:list) {

            Element pnode = node.getParent();

            System.out.println(node.getName() + "=" + node.getText());

            System.out.println(pnode.getName() + ":" + pnode.attribute(0).getName() +

                    " = " + pnode.attributeValue("no"));

            System.out.println("------------------");

        }

        //快速搜索属性

        List<Node> list2 = document.selectNodes("books/book");

        for (Node node:list2) {

            //获取节点的属性值

            System.out.println("no="+node.valueOf("@no"));

        }

    }

}

5.DOM4J创建XML文件

/*

* <books>

   <book no = "0103410">

      <name>还珠格格</name>

      <author>琼瑶</author>

      <publish>芒果台出版社</publish>

      <price>34.5</price>

   </book>

  </books>

* */

public class CreateXMLFileByDom4J {

    public static void main(String[] args) throws IOException {

        //创建一个文档对象

        Document document = DocumentHelper.createDocument();

        //创建一个根节点

        Element root = document.addElement("books");

        Element book = root.addElement("book").addAttribute("no", "0103410");

        book.addElement("name").setText("还珠格格");

        book.addElement("author").setText("琼瑶");

        book.addElement("publish").setText("芒果台出版社");

        book.addElement("price").setText("34.5");



        //创建一个文档的输出格式对象

        OutputFormat fmt = OutputFormat.createPrettyPrint();//创建漂亮的格式

        fmt.setEncoding("utf-8");//设置编码





        File file = new File("src/java/bk.xml");

        FileWriter fw = new FileWriter(file);



        //xml文件输出流

        XMLWriter writer = new XMLWriter(fw,fmt);//装饰器模式

        writer.write(document);

        writer.flush();

        writer.close();

    }

}

 

Android pull解析

反射reflect

*.java源文件编译为.class字节码文件

* 类加载机制:将一个类装载到jvm虚拟机等待执行的过程(字节码文件的加载过程)

* 1.加载  先去父类找,如果找到了就只加载父类,没找到去子类找,这时父类和子类都加载,加载顺序是先父类再子类(如果是A->B->C的继承关系,AC具有相同属性,B没有,这时候不会跳过B,会先加载A,再加载B再加载C),先静态快再静态属性。

*

* 2.验证(连接操作)

* 3.准备(连接操作)为静态成员变量赋默认值

* 4.解释(连接操作)

*

* 5.初始化(对类中静态成分执行初始化,为静态变量赋值,执行静态的初始化块)

* 将这些方法放到栈内存的方法区中

* 6.使用(调用成员变量)

* 7.卸载

反射:一个正在运行的类通过反射机制获取到类中的具体信息(包含在Class实例中)

 

获取Class类对象的三种方法:

方法一:调用类的class属性获取。默认不初始化

       Class class1 = Student.class;

方法二:通过实例对象的getClass()方法获取

       Student stu = new Student();

       Class class1 = stu.getClass();

方法三:通过类加载器加载

       默认不初始化

       Student.class.getClassLoader().loadClass("com.wan.reflect.Student");

       默认初始化

       Class.forName("com.wan.reflect.Demo2");

       不初始化

Class.forName("com.wan.reflect.Demo2",false,Demo2.class.getClassLoader());

 

Demo

Class clz = Class.forName("com.wan.reflect.Student",false,com.wan.reflect.Student.class.getClassLoader());

    Object obj = clz.newInstance();//利用Class实例化对象(前提是被实例化的对象所在类必须包含默认的无参构造器)

    ((Student)obj).setSno(10);



    Field[] fields = clz.getFields();//获取类中公开属性

    fields = clz.getDeclaredFields();//获取类中所有属性

    for (Field f:fields) {

        //属性-属性类型-访问修饰符类型(protected,private,public,默认0)

        System.out.println(f + "------" + f.getType()+"------"+f.getModifiers());

    }

    System.out.println("-=-=-=--=-=-=-=-=-=-=-");

    Field field = clz.getDeclaredField("sno");//获取其中某一个属性对象

    System.out.println(field.getName());//获取属性名

    System.out.println(field.getType());//获取类型

    System.out.println(field.get(obj));//获取当前属性在指定对象上的值

    field.set(obj, 11);//设置指定对象的改属性值

    System.out.println(field.get(obj));

    System.out.println("-=-=-=--=-=-=-=-=-=-=-");

    //获取方法

    Method[] methods = clz.getDeclaredMethods();

    for (Method m:methods) {

        System.out.println(m);

    }

    //获取指定方法(通过方法名,属性类型获取方法对象)

    Method method = clz.getMethod("setSex",clz.getDeclaredField("sex").getType());

    System.out.println("指定method:"+method);

    //执行方法

    method.invoke(obj, "未知");

    System.out.println("obj:"+obj);



    Method method1 = clz.getMethod("getSex");

    //执行方法并获取返回值

    Object r = method1.invoke(obj);

    System.out.println(r);

    System.out.println("-=-=-=--=-=-=-=-=-=-=-");

    //获取构造器

    Constructor[] constructors = clz.getDeclaredConstructors();

    for (Constructor constructor:constructors) {

        System.out.println(constructor);

    }

}

f.getModifiers()//访问修饰符类型

Spring反射原理:

  1. 解析XML, <beans>根节点,<bean>对象,<property>属性,<text>属性值
  2. 创建bean工厂,传bean的id获取bean对象

对象克隆

public class ObjectClone {

    public static <T> T copy(Object source, Class<T> T){

        //获取指定对象的Class对象

        if (source != null){

            Class<T> clz = T;

            try {

                //创建新对象

                T newObj = clz.newInstance();

                //获取当前包中所有属性

                Field[] fields = clz.getDeclaredFields();

                for (Field f:fields) {

                    //获取set get方法的名字

                    String method_set_name = "set" + f.getName().substring(0,1).toUpperCase() + f.getName().substring(1);

                    String method_get_name = "get" + f.getName().substring(0,1).toUpperCase() + f.getName().substring(1);

                    //通过方法名和参数类型获得方法对象

                    Method method_set = clz.getMethod(method_set_name, f.getType());

                    Method method_get = clz.getMethod(method_get_name);

                    //将源对象的值赋给新对象

                    Object field_value = method_get.invoke(source);

                    method_set.invoke(newObj, field_value);

                }

                return newObj;

            } catch (InstantiationException e) {

                e.printStackTrace();

            } catch (IllegalAccessException e) {

                e.printStackTrace();

            } catch (NoSuchMethodException e) {

                e.printStackTrace();

            } catch (InvocationTargetException e) {

                e.printStackTrace();

            }

        }

        return null;

    }

    public static void main(String[] args) {

        System.out.println(ObjectClone.copy(new Student(1,"王老五",13,"化学系"),Student.class));

        System.out.println(ObjectClone.copy(new Test(),Test.class));

    }

}

解析beans,Spring解析bean原理

public class BeanFactory {

    //初始化一个map集合存储所有的bean对象

    private Map<String, Object> beans;



    public BeanFactory() {

    }

    //根据beans文件解析

    public BeanFactory(String config){

        try {

            beans = new HashMap<String, Object>();

            //创建解析器

            SAXReader reader = new SAXReader();

            //解析配置文件获取document文件

            Document document = reader.read(config);

            //获取所有bean节点

            List<Node> list = document.selectNodes("beans/bean");

            if (list != null){

                for (Node node:list) {

                    //获取bean节点中的id和class属性值

                    String id = node.valueOf("@id");

                    String clzName = node.valueOf("@class");

                    //加载指定类路径获取Class对象

                    Class clz = Class.forName(clzName);

                    //创建实例

                    Object obj = clz.newInstance();

                    //将实例装进map,键为id

                    beans.put(id, obj);

                    //获取bean节点下的所有属性节点

                    List<Node> props = node.selectNodes("property");

                    //循环属性节点

                    for (Node n:props) {

                        //获取每个属性节点的name属性名---value属性值---ref关联

                        String pName = n.valueOf("@name");

                        String pValue = n.valueOf("@value");

                        String pRef = n.valueOf("@ref");

                        //根据属性名获取set方法名字

                        String method_set_name = "set" + pName.substring(0,1).toUpperCase() + pName.substring(1);

                        //根据set方法的名字和属性类型获取set方法

                        Method method_set = clz.getMethod(method_set_name, clz.getDeclaredField(pName).getType());

                        //如果有关联直接去map中取数据,否则运行set方法将value值设给属性

                        if ("".equals(pRef)){

                            Class c = method_set.getParameterTypes()[0];
//根据属性的类型将String转换为相应类型值后再set
                            method_set.invoke(obj, Utils.getValue(c.getName(),pValue));

                        }else {

                            method_set.invoke(obj, beans.get(pRef));

                        }

                    }

                }

            }

        } catch (DocumentException e) {

            e.printStackTrace();

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        } catch (IllegalAccessException e) {

            e.printStackTrace();

        } catch (InstantiationException e) {

            e.printStackTrace();

        } catch (NoSuchMethodException e) {

            e.printStackTrace();

        } catch (InvocationTargetException e) {

            e.printStackTrace();

        } catch (NoSuchFieldException e) {

            e.printStackTrace();

        }

    }

    public Object getBean(String id){

        return beans == null ? null : beans.get(id);

    }

    public static void main(String[] args) {

        BeanFactory bf = new BeanFactory("src/java/beans.xml");

        UserService us = (UserService)bf.getBean("userService");

        us.register();

    }

}

转换为相应类型:

public class Utils {

    public static Object getValue(String type, String value){

        if ("int".equals(type)){

            return Integer.parseInt(value);

        }else if ("short".equals(type)){

            return Short.parseShort(value);

        }else if ("long".equals(type)){

            return Long.parseLong(value);

        }else if ("float".equals(type)){

            return Float.parseFloat(value);

        }else if ("double".equals(type)){

            return Double.parseDouble(value);

        }else if ("char".equals(type)){

            return value.charAt(0);

        }else if ("byte".equals(type)){

            return Byte.parseByte(value);

        }else if ("boolean".equals(type)){

            return Boolean.parseBoolean(value);

        }else {

            return value;

        }

    }

}

 

知识点:

一、Java只有两种成员变量与对象无关

  1. 基本数据类型
  2. 静态成员(静态属性,静态方法)

 

  • Java中所有类都是Class类实例。Class代表的是jvm中正在执行的一个类的实例,

Class中包含了当前实例的运行信息,内部构造(成员变量,方法,注解,实现接口。。。)

 

 

  • Object是所有类的父类。Object也是Class类的一个实例
  • DI/IOC(控制反转):程序员需要手动new对象的操作交给了框架来做了,spring利用反射机制读取xml文件,利用反射实现对象,property值也通过反射set方法注入到对象里面。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值