Skip to content

Instantly share code, notes, and snippets.

@rogargon
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rogargon/7073e017e7b5f297e125 to your computer and use it in GitHub Desktop.
Save rogargon/7073e017e7b5f297e125 to your computer and use it in GitHub Desktop.
Example of using XQuery to process and input URL and create objects from the XQuery results.
package cat.udl.eps.softarch;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.xquery.*;
/**
* Created by http://rhizomik.net/~roberto/
*/
public class XQueryHelper {
private static final Logger log = Logger.getLogger(XQueryHelper.class.getName());
private XQPreparedExpression expr;
private XQConnection conn;
private JAXBContext jaxbContext;
private Unmarshaller jaxbUnmarshaller;
static final String apiURL = "http://musicbrainz.org/ws/2/artist/cc2c9c3c-b7bc-4b8b-84d8-4fbd8779e493?inc=releases";
static final String albumsXQ =
"declare namespace mmd=\"http://musicbrainz.org/ns/mmd-2.0#\";\n"
+ "declare variable $doc external;\n"
+ "for $r in $doc//mmd:release\n"
+ "let $years-from-date:=$r/mmd:date[matches(text(),\"^\\d{4}-\\d{2}-\\d{2}$\")]/year-from-date(text())\n"
+ "let $years:=$r/mmd:date[matches(text(),\"^\\d{4}$\")]\n"
+ "return\n"
+ "<song>\n"
+ " <title>{$r/mmd:title/text()}</title>\n"
+ " <artist>{$doc//mmd:artist/mmd:name/text()}</artist>\n"
+ " <countries>{distinct-values($r//mmd:country)}</countries>\n"
+ " <year>{min(($years,$years-from-date))}</year>\n"
+ "</song>";
@XmlRootElement
private static class Song {
@XmlElement String title;
@XmlElement String artist;
@XmlElement String countries;
@XmlElement Integer year;
@Override
public String toString() {
return "Title: "+title+"\n"+"Artist: "+artist+"\n"+"Countries: "+countries+"\n"+"Year: "+year+"\n";
}
}
XQueryHelper(String xquery, URL url)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, XQException, IOException, JAXBException {
URLConnection urlconn = url.openConnection();
urlconn.setReadTimeout(50000);
XQDataSource xqds = (XQDataSource) Class.forName("net.sf.saxon.xqj.SaxonXQDataSource").newInstance();
this.conn = xqds.getConnection();
this.expr = conn.prepareExpression(xquery);
this.expr.bindDocument(new javax.xml.namespace.QName("doc"), urlconn.getInputStream(), null, null);
this.jaxbContext = JAXBContext.newInstance(Song.class);
this.jaxbUnmarshaller = jaxbContext.createUnmarshaller();
}
ArrayList<Song> getSongs() {
ArrayList<Song> songs = new ArrayList<Song>();
try {
XQResultSequence rs = this.expr.executeQuery();
while (rs.next()) {
XQItem item = rs.getItem();
Song song = (Song) jaxbUnmarshaller.unmarshal(item.getNode());
songs.add(song);
}
}
catch (Exception e) {
log.log(Level.SEVERE, e.getMessage());
}
finally { close(); }
return songs;
}
private void close() {
try {
this.expr.close();
this.conn.close();
} catch (XQException e) {
log.log(Level.SEVERE, e.getMessage());
}
}
public static void main(String[] args) {
try {
XQueryHelper xQueryHelper = new XQueryHelper(albumsXQ, new URL(apiURL));
ArrayList<Song> songs = xQueryHelper.getSongs();
for (Song song : songs)
System.out.println(song);
} catch (Exception e){
e.printStackTrace();
}
}
}
@rogargon
Copy link
Author

Requires a logging implementation and Saxon (including Saxon-XQJ).
For instance, as Maven dependencies:

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.2</version>
    </dependency>
    <dependency>
        <groupId>net.sf.saxon</groupId>
        <artifactId>Saxon-HE</artifactId>
        <version>9.4</version>
    </dependency>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment