解析XML之Digester

本文讲解,如何使用Digester将XML文档和Java对象映射,主要以撸代码为主。

引入 Maven pom依赖:

       
            org.apache.commons
            commons-digester3
            3.2
            with-deps
        

现有XML文件books.xml,其文件内容如下:



    
        
            施耐庵
            罗贯中
        
        元末明初
        
            水浒
            忠义水浒传
        
        小说
    
    
        
            吴承恩
        
        明朝
        
            西游释厄传
        
        
            浪漫主义章回体长篇神魔小说
        
    
    
        
            曹雪芹
            程伟元
            高鹗
        
        18世纪中叶
        
            石头记
            情僧录
            风月宝鉴
            金陵十二钗
            金玉缘
        
        
            章回体长篇小说
        
    

本文提供两种将XML映射成Java对象的方式,分别是使用注解和是不使用注解。

1.映射方式一不使用注解

创建对象用来装载XML文档中的内容:
1、Name.java,用来存放books/book/byname/name标签中的内容。

public class Name {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2、Byname.java,用来存放books/book/byname/name标签集合。

public class Byname {
    private List name;
    public List getName() {
        return name;
    }
    public void setName(List name) {
        this.name = name;
    }
    /**
    */
    public void addByname(Name name){
        if(name==null){
            return;
        }
        if(this.name==null){
            this.name = new ArrayList<>();
        }
        this.name.add(name);
    }
}


3、AuthorName.java,用来存放books/book/author/name标签中的内容。

public class AuthorName {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

4、Author.java,用来存放books/book/author/name标签集合

public class Author {
    private List names;
    public List getNames() {
        return names;
    }
    public void setNames(List names) {
        this.names = names;
    }
    public void addAuthorName(AuthorName name) {
        if (name == null) {
            return;
        }
        if (this.names == null) {
            this.names = new ArrayList<>();
        }
        this.names.add(name);
    }
}

5、Book.java,用来存放books/book标签中的内容

public class Book {
    private Author author;
    private Byname byname;
    private String creationDate;
    private String literaryStyle;
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Byname getByname() {
        return byname;
    }
    public void setByname(Byname byname) {
        this.byname = byname;
    }
    public Author getAuthor() {
        return author;
    }
    public void setAuthor(Author author) {
        this.author = author;
    }
    public String getCreationDate() {
        return creationDate;
    }
    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }
    public String getLiteraryStyle() {
        return literaryStyle;
    }
    public void setLiteraryStyle(String literaryStyle) {
        this.literaryStyle = literaryStyle;
    }
    public void addByname(Byname byname){
        this.byname = byname;
    }
    public void addAuthor(Author author){
        this.author = author;
    }
}

6、Books.java,用来存放books/book标签集。

public class Books {
    private List bookList;
    public List getBookList() {
        return bookList;
    }
    public void setBookList(List bookList) {
        this.bookList = bookList;
    }
    public void addBooks(Book book) {
        if (book == null) {
            return;
        }
        if (this.bookList == null) {
            this.bookList = new ArrayList<>();
        }
        this.bookList.add(book);
    }
}

7、Test1.java,生成映射XML文档到Java对象和测试

public class Test1 {

    public static Books parseXml(File xmlFile) throws IOException, SAXException {
        Digester digester = new Digester();
        digester.setValidating(false);
        //跟标签/books和Books对象映射
        digester.addObjectCreate("books", Books.class);

        //标签/books/book和Book对象映射
        digester.addObjectCreate("books/book", Book.class);

        //将/books/book标签的所有属性映射到Book对象的属性上,在这里映射的是/books/book标签的name属性。
        digester.addSetProperties("books/book");
        //或者使用下面这种方式代替,digester.addSetProperties("books/book");这种方式要求标签属性名和对象中的字段要保持命名一致才可以映射上。
//        digester.addSetProperties("books/book","name","name");

        //标签books/book/creationDate,和Book对象的creationDate属性映射
        digester.addBeanPropertySetter("books/book/creationDate", "creationDate");
        //标签books/book/literaryStyle,和Book对象的literaryStyle属性映射
        digester.addBeanPropertySetter("books/book/literaryStyle", "literaryStyle");

        //标签books/book/author和Author对象映射
        digester.addObjectCreate("books/book/author", Author.class);

        //标签books/book/author/name和AuthorName对象映射
        digester.addObjectCreate("books/book/author/name", AuthorName.class);
        //标签books/book/author/name,和AuthorName对象的name属性映射
        digester.addBeanPropertySetter("books/book/author/name", "name");

        //标签books/book/byname和Byname对象映射
        digester.addObjectCreate("books/book/byname", Byname.class);
        //标签books/book/byname/name和Name对象映射
        digester.addObjectCreate("books/book/byname/name", Name.class);
        //标签books/book/byname/name,和Byname对象的name属性映射
        digester.addBeanPropertySetter("books/book/byname/name", "name");

        //把Book标签对象添加到Book对象中,需要保证Books对象中有addBooks该方法,用于添加装载XML标签内容后的对象信息
        digester.addSetNext("books/book", "addBooks");
        //把Author标签对象和Byname标签对象添加到Book对象中,需要保证Book对象中有addAuthor和addByname方法,用于添加装载XML标签内容后的对象信息
        digester.addSetNext("books/book/author", "addAuthor");
        digester.addSetNext("books/book/byname", "addByname");

        //把Name标签对象添加到Byname对象中,需要保证Byname对象中有addByname方法(命名任意,只需要对应上即可),用于添加装载XML标签内容后的对象信息
        digester.addSetNext("books/book/byname/name", "addByname");
        //把AuthorName标签对象添加到Author对象中,需要保证Author对象中有addAuthorName方法(命名任意,只需要对应上即可),用于添加装载XML标签内容后的对象信息
        digester.addSetNext("books/book/author/name", "addAuthorName");
        Object obj = digester.parse(xmlFile);
        if (obj instanceof Books) {
            return (Books) obj;
        }
        return null;
    }

    public static void main(String[] args) throws IOException, SAXException {
        String baseDir = System.getProperty("user.dir");
        File xmlFile = new File(baseDir + "/src/main/resources/books.xml");
        Books books = parseXml(xmlFile);
    }
}

2.映射方式二使用注解

Digester3根据注解来映射Java对象和XML文档,在方式一的基础上的对象添加注解即可,具体如下:
1、Name.java,用来存放books/book/byname/name标签中的内容。

//books/book/byname/name标签和Name对象映射
@ObjectCreate(pattern = "books/book/byname/name")
public class Name {
    //books/book/byname/name标签内容和AuthorName的name属性映射
    @BeanPropertySetter(pattern = "books/book/byname/name")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2、Byname.java,用来存放books/book/byname/name标签集合。

//books/book/byname标签和Byname对象映射
@ObjectCreate(pattern = "books/book/byname")
public class Byname {

    private List name;

    public List getName() {
        return name;
    }

    public void setName(List name) {
        this.name = name;
    }

    //将books/book/byname/name标签的内容对象添加到Byname对象中
    @SetNext
    public void addByname(Name name){
        if(name==null){
            return;
        }
        if(this.name==null){
            this.name = new ArrayList<>();
        }
        this.name.add(name);
    }
}

3、AuthorName.java,用来存放books/book/author/name标签中的内容。

//books/book/author/anme标签和AuthorName对象映射
@ObjectCreate(pattern = "books/book/author/name")
public class AuthorName {
    @BeanPropertySetter(pattern = "books/book/author/name")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4、Author.java,用来存放books/book/author/name标签中的内容。

//books/book/author标签和Author对象映射
@ObjectCreate(pattern = "books/book/author")
public class Author {
    private List names;

    public List getNames() {
        return names;
    }

    public void setNames(List names) {
        this.names = names;
    }
    //将books/book/author/name标签的内容对象添加到Author对象中
    @SetNext
    public void addAuthorName(AuthorName name) {
        if (name == null) {
            return;
        }
        if (this.names == null) {
            this.names = new ArrayList<>();
        }
        this.names.add(name);
    }
}

5、Book.java,用来存放books/book标签中的内容

//books/book标签和Book对象映射
@ObjectCreate(pattern = "books/book")
public class Book {

    private Author author;

    private Byname byname;

    //books/book/creationDate标签内容和Book的creationDate属性映射
    @BeanPropertySetter(pattern = "books/book/creationDate")
    private String creationDate;
    //books/book/literaryStyle标签内容和Book的literaryStyle属性映射
    @BeanPropertySetter(pattern = "books/book/literaryStyle")
    private String literaryStyle;
    //将/books/book标签的所有属性映射到Book对象的属性上,在这里映射的是/books/book标签的name属性。
    @SetProperty(pattern = "books/book")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Byname getByname() {
        return byname;
    }

    public void setByname(Byname byname) {
        this.byname = byname;
    }

    public Author getAuthor() {
        return author;
    }

    public void setAuthor(Author author) {
        this.author = author;
    }

    public String getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }

    public String getLiteraryStyle() {
        return literaryStyle;
    }

    public void setLiteraryStyle(String literaryStyle) {
        this.literaryStyle = literaryStyle;
    }

    //将books/book/byname标签的内容对象添加到Book对象中
    @SetNext
    public void addByname(Byname byname){
        this.byname = byname;
    }
    //将books/book/author标签的内容对象添加到Book对象中
    @SetNext
    public void addAuthor(Author author){
        this.author = author;
    }
}

6、Books.java,用来存放books/book标签集。

//books标签和Books对象映射
@ObjectCreate(pattern = "books")
public class Books {

    private List bookList;

    public List getBookList() {
        return bookList;
    }

    public void setBookList(List bookList) {
        this.bookList = bookList;
    }
    //将books/book标签的内容对象添加到Books对象中
    @SetNext
    public void addBooks(Book book) {
        if (book == null) {
            return;
        }
        if (this.bookList == null) {
            this.bookList = new ArrayList<>();
        }
        this.bookList.add(book);
    }
}

7、Test2.java测试Digester3注解映射XML和Java对象。

public class Test2 {

    public static Books readBooks(File xmlPath, Class XmlClazz) throws IOException, SAXException {
        Digester digester = getLoader(XmlClazz).newDigester();
        return digester.parse(xmlPath);
    }

    public static DigesterLoader getLoader(final Class XmlClazz) {
        return newLoader(new FromAnnotationsRuleModule() {
            @Override
            protected void configureRules() {
                bindRulesFrom(XmlClazz);
            }
        });
    }

    public static void main(String[] args) throws IOException, SAXException {
        String baseDir = System.getProperty("user.dir");
        File xmlFile = new File(baseDir + "/src/main/resources/books.xml");
        Books books = readBooks(xmlFile, Books.class);
    }

}

你可能感兴趣的:(解析XML之Digester)