I have an xml file with lots of tags and subtags. I want to model that xml file in a java class. For example, for below xml file I want to create separate book class with author n title as field.
class Book{
private string title;
private String author
}
For parsing I am using the following code
def catalogue= new XmlParser().parse(file)
Book b =new Book()
b.setTitle(catalogue.book.title.text())
b.setAuthor(catalogue.book.author.text())
Sample xml file
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
</book>
</catalog>
My question is if the xml file contains lots of tag n subtags then manually setting the value of each class field is not a gud approach.Is there any shorter way to do this.
You can use jaxb. It uses annotations on fields. I think that you can also make jaxb create the java class from a sample xm l file.
If you have to parse many books you can iterate over the <book>
tags on your XML. For example:
import groovy.transform.Canonical
@Canonical
class Book {
String title, author
}
def text = """
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
</book>
<book id="bk102">
<author>Orwell, George</author>
<title>1984</title>
</book>
<book id="bk103">
<author>Huxley, Aldous</author>
<title>Brave New World</title>
</book>
</catalog>
"""
def catalog = new XmlParser().parseText(text)
def books = catalog.book.collect {
new Book(title: it.title.text(), author: it.author.text())
}
println books
...outputs [Book(XML Developer's Guide, Gambardella, Matthew), Book(1984, Orwell, George), Book(Brave New World, Huxley, Aldous)]
Notice that I'm using the @Canonical
transformation, but it's just to get a nice toString()
method for free :)
Update : Sorry, I didn't notice that the Book class is in Java. I assume you cannot touch that. But still, you can parse that xml with:
def catalog = new XmlParser().parseText(text)
def books = catalog.book.collect {
def b = new Book()
b.setAuthor(it.author.text())
b.setTitle(it.title.text())
b
}
Another option, is to only set the properties on the Book object where the same named properties exist in the xml file...
So, given an xml file like this (and a java class Book
as you specified in the question):
def xml = '''<catalog>
| <book id="bk101">
| <author>Gambardella, Matthew</author>
| <title>XML Developers Guide</title>
| </book>
| <book id="bk102">
| <author>Yates, Tim</author>
| <title>Munging XML with Groovy</title>
| </book>
|</catalog>'''.stripMargin()
You can generate a list of Book
objects (setting the fields that exist in the xml), like so:
def bookList = new XmlParser().parseText( xml ).with { doc ->
doc.book.collect { xmlbook ->
new Book().with { book ->
xmlbook.children()*.name().intersect( Book.declaredFields.grep { !it.synthetic }.name ).each { field ->
book.@"$field" = xmlbook."$field".text()
}
book
}
}
}
Then to print out bookList
, we get:
bookList.each {
println "Book author:$it.author, title:$it.title"
}
Which prints:
Book author:Gambardella, Matthew, title:XML Developers Guide
Book author:Yates, Tim, title:Munging XML with Groovy
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.