zoukankan      html  css  js  c++  java
  • Commons JXPath

    JXPath 除了可以 XPath 语法访问 JavaBeans、DOM/JDOM,也可以对其属性赋值。

    以下面的 JavaBeans 为例。

    package com.huey.jxpath;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Book {
    
        private String title;
        private Author[] authors;
        private Publisher publisher;
        private String isbn;
        private double price;
        
    }
    Book.java
    package com.huey.jxpath;
    
    import java.util.Date;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Author {
    
        private String firstName;
        private String lastName;
        private char gender;
        private Date birthday;
        
    }
    Author.java
    package com.huey.jxpath;
    
    import java.util.Map;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Publisher {
    
        private String name;
        private String address;
        private Map<String, String> contacts;
        
    }
    Publisher.java

    初始化:

    Author[] authors;
    Publisher publisher;
    Book book;
    
    authors = new Author[] {
        new Author("Eric", "Freeman", 'F', new Date()),
        new Author("ElElisabeth", "Freeman", 'M', new Date())
    };
    
    Map<String, String> contacts = new HashMap<String, String>();
    contacts.put("tel", "010-12345678");
    contacts.put("fax", "010-87654321");
    contacts.put("email", "test@163.com");
    publisher = new Publisher("中国电力出版社", "北京市XX区YY路Z号", contacts);
    
    book = new Book("Head First Design Patterns", authors, publisher, "9787508353937", 98.0);

    Setting Properties

    JXPathContext context = JXPathContext.newContext(book);
    context.setValue("publisher/name", "人民邮电出版社");
    context.setValue("publisher/contacts/attribute::email", "test@gmail.com");

    Creating Objects

    当对 JavaBean 的复杂数据类型属性设置值时,如果属性没有实例化,则会抛出一个 JXPathException 异常。实现 AbstractFactory 接口后,再调用 context.createPath 方法,能够在复杂数据类型对象为 null 时,为其实例化。context.createPathAndSetValue 方法能够在实例化对象的同时设置值。

    package com.huey.jxpath;
    
    import java.lang.reflect.Array;
    import java.util.HashMap;
    
    import org.apache.commons.jxpath.AbstractFactory;
    import org.apache.commons.jxpath.JXPathContext;
    import org.apache.commons.jxpath.Pointer;
    
    public class BookFactory extends AbstractFactory {
    
        @Override
        public boolean createObject(JXPathContext context, Pointer pointer,
                Object parent, String name, int index) {
            
            if (parent instanceof Book && "authors".equals(name)) {    
                Book book = (Book) parent;
                if (book.getAuthors() == null) {
                    book.setAuthors(new Author[]{});
                }
                int newSize = index + 1;
                int oldSize = book.getAuthors().length;
                if (newSize > oldSize) {
                    Author[] newAuthors = (Author[]) resizeArray(book.getAuthors(), newSize);
                    book.setAuthors(newAuthors);
                }
                return true;
            }
            if (parent instanceof Book && "publisher".equals(name)) {
                ((Book)parent).setPublisher(new Publisher());
                return true;
            }
            if (parent instanceof Publisher && "contacts".equals(name)) {
                ((Publisher)parent).setContacts(new HashMap<String, String>());
                return true;
            }
            return false;
        }
        
        /**
         * 调整数组长度,当新的数组长度大于旧的数组长度时,实例化所有新增的元素
         * @param oldArray
         * @param newSize
         * @return
         */
        private Object resizeArray (Object oldArray, int newSize) {
            int oldSize = Array.getLength(oldArray);
            Class<?> elementType = oldArray.getClass().getComponentType();
            
            Object newArray = Array.newInstance(elementType, newSize);
            int preserveLength = Math.min(oldSize, newSize);
            if (preserveLength > 0) {
                System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
            }
            try {
                for (int i = preserveLength; i < newSize; i++) {
                    Array.set(newArray, i, elementType.newInstance());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return newArray;
        }
        
    }
    JXPathContext context = JXPathContext.newContext(new Book());
    context.setFactory(new BookFactory());
    context.createPathAndSetValue("title", "hello jxpath");
    context.createPathAndSetValue("authors[1]/gender", 'F');
    // Map 对象的 xpath 必须使用 contacts/email 或 contacts/child::email 而不能使用 contacts[@email] 或 contacts/attribute::email
    context.createPathAndSetValue("publisher/contacts/child::email", "test@gmial.com");
  • 相关阅读:
    Linux学习之网络基础
    C# 随笔
    最牛B的编码套路
    c++ Primer 第七章不熟悉知识点总结
    oracle求表的倒数二行数据
    c++ Primer 第六章不熟悉知识点总结
    c++ Primer 第五章不熟悉知识点总结
    c++ Primer 第四章不熟悉知识点总结
    c++ Primer 第三章不熟悉知识点总结
    骑驴找马
  • 原文地址:https://www.cnblogs.com/huey/p/4698516.html
Copyright © 2011-2022 走看看