What Java Xml Library Do You Recommend (To Replace Dom4J)

XML and Dom4J. How to retrieve values with the iterator?

With XPath functionality of dom4j:

// Place the root element of theXML into a variable
List<? extends Node> items =
(List<? extends Node>)theXML.selectNodes("//rss/channel/item");

// RFC-dictated date format used with RSS
DateFormat dateFormatterRssPubDate =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH);

// today started at this time
DateTime timeTodayStartedAt = new DateTime().withTimeAtStartOfDay();

for (Node node: items) {
String pubDate = node.valueOf( "pubDate" );
DateTime date = new DateTime(dateFormatterRssPubDate.parse(pubDate));
if (date.isAfter(timeTodayStartedAt)) {
// it's today, do something!
System.out.println("Today: " + date);
} else {
System.out.println("Not today: " + date);
}
}

Dom4j needs jaxen dependency for XPath to work. I used JodaTime to compare the dates, as it's a lot cleaner than using java builtin dates. Here's the full example.

Note that dom4j is not really maintained, so you might be also interested in this discussion about dom4j alternatives.

Which Java DOM Wrapper is the Best or Most Popular?

I like XOM, because I like the way Elliotte Rusty Harold thinks. Of the ones you mention I belive it's the one that strays away from the DOM standard API:s the most, but I consider that a benefit.

I once implemented a DOM library for Cocoa, and XOM was my inspiration.

I've worked with JDOM as well, and there's absolutely nothing wrong with it, although I do prefer XOM.

Which is the best library for XML parsing in java

Actually Java supports 4 methods to parse XML out of the box:

DOM Parser/Builder: The whole XML structure is loaded into memory and you can use the well known DOM methods to work with it. DOM also allows you to write to the document with Xslt transformations.
Example:

public static void parse() throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
File file = new File("test.xml");
Document doc = builder.parse(file);
// Do something with the document here.
}

SAX Parser: Solely to read a XML document. The Sax parser runs through the document and calls callback methods of the user. There are methods for start/end of a document, element and so on. They're defined in org.xml.sax.ContentHandler and there's an empty helper class DefaultHandler.

public static void parse() throws ParserConfigurationException, SAXException {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
SAXParser saxParser = factory.newSAXParser();
File file = new File("test.xml");
saxParser.parse(file, new ElementHandler()); // specify handler
}

StAx Reader/Writer: This works with a datastream oriented interface. The program asks for the next element when it's ready just like a cursor/iterator. You can also create documents with it.
Read document:

public static void parse() throws XMLStreamException, IOException {
try (FileInputStream fis = new FileInputStream("test.xml")) {
XMLInputFactory xmlInFact = XMLInputFactory.newInstance();
XMLStreamReader reader = xmlInFact.createXMLStreamReader(fis);
while(reader.hasNext()) {
reader.next(); // do something here
}
}
}

Write document:

public static void parse() throws XMLStreamException, IOException {
try (FileOutputStream fos = new FileOutputStream("test.xml")){
XMLOutputFactory xmlOutFact = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xmlOutFact.createXMLStreamWriter(fos);
writer.writeStartDocument();
writer.writeStartElement("test");
// write stuff
writer.writeEndElement();
}
}

JAXB: The newest implementation to read XML documents: Is part of Java 6 in v2. This allows us to serialize java objects from a document. You read the document with a class that implements a interface to javax.xml.bind.Unmarshaller (you get a class for this from JAXBContext.newInstance). The context has to be initialized with the used classes, but you just have to specify the root classes and don't have to worry about static referenced classes.
You use annotations to specify which classes should be elements (@XmlRootElement) and which fields are elements(@XmlElement) or attributes (@XmlAttribute, what a surprise!)

public static void parse() throws JAXBException, IOException {
try (FileInputStream adrFile = new FileInputStream("test")) {
JAXBContext ctx = JAXBContext.newInstance(RootElementClass.class);
Unmarshaller um = ctx.createUnmarshaller();
RootElementClass rootElement = (RootElementClass) um.unmarshal(adrFile);
}
}

Write document:

public static void parse(RootElementClass out) throws IOException, JAXBException {
try (FileOutputStream adrFile = new FileOutputStream("test.xml")) {
JAXBContext ctx = JAXBContext.newInstance(RootElementClass.class);
Marshaller ma = ctx.createMarshaller();
ma.marshal(out, adrFile);
}
}

Examples shamelessly copied from some old lecture slides ;-)

Edit: About "which API should I use?". Well it depends - not all APIs have the same capabilities as you see, but if you have control over the classes you use to map the XML document JAXB is my personal favorite, really elegant and simple solution (though I haven't used it for really large documents, it could get a bit complex). SAX is pretty easy to use too and just stay away from DOM if you don't have a really good reason to use it - old, clunky API in my opinion. I don't think there are any modern 3rd party libraries that feature anything especially useful that's missing from the STL and the standard libraries have the usual advantages of being extremely well tested, documented and stable.

Best XML parser for Java

If speed and memory is no problem, dom4j is a really good option. If you need speed, using a StAX parser like Woodstox is the right way, but you have to write more code to get things done and you have to get used to process XML in streams.

How to pretty print XML from Java?

Now it's 2012 and Java can do more than it used to with XML, I'd like to add an alternative to my accepted answer. This has no dependencies outside of Java 6.

import org.w3c.dom.Node;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;

/**
* Pretty-prints xml, supplied as a string.
* <p/>
* eg.
* <code>
* String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>");
* </code>
*/
public class XmlFormatter {

public String format(String xml) {

try {
final InputSource src = new InputSource(new StringReader(xml));
final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
final Boolean keepDeclaration = Boolean.valueOf(xml.startsWith("<?xml"));

//May need this: System.setProperty(DOMImplementationRegistry.PROPERTY,"com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl");

final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
final LSSerializer writer = impl.createLSSerializer();

writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); // Set this to true if the output needs to be beautified.
writer.getDomConfig().setParameter("xml-declaration", keepDeclaration); // Set this to true if the declaration is needed to be outputted.

return writer.writeToString(document);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {
String unformattedXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +
" xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +
" xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +
" <Query>\n" +
" <query:CategorySchemeWhere>\n" +
" \t\t\t\t\t <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +
" </query:CategorySchemeWhere>\n" +
" </Query>\n\n\n\n\n" +
"</QueryMessage>";

System.out.println(new XmlFormatter().format(unformattedXml));
}
}

Simple way to do Xml in Java

I recommend XOM. Its API is clear and intuitive.



Related Topics



Leave a reply



Submit