首页 > 代码库 > Java XML - JDOM2

Java XML - JDOM2

Java XML - JDOM2 - Introduction (2014/9/28 22:10:49)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" data-en_id="77911232" src=""></iframe>

What is JDOM

JDOM is an in-memory XML model that can be used to read, write, create and modify XML Documents. JDOM is similar to DOM in that they both provide an in-memory XML document model, but while DOM is designed to work the same in multiple languages (C, C++, ECMAScript, Java, JScript, Lingo, PHP, PLSQL, and Python [http://www.w3.org/DOM/Bindings]), JDOM is designed only for Java and uses the natural Java-specific features that the DOM model avoids. For this reason JDOM intentionally does not follow the w3c DOM standard. JDOM is not an XML parser but it can use a SAX, StAX or DOM parser to build the JDOM document. JDOM versions since JDOM 2.0.0 (JDOM2) all use the native language features of Java6 and later like Generics, Enums, var-args, co-variant return types, etc.

In the tutorials listed below we provide you with examples of all key functionalities of JDOM2. However before you start seeing the examples, it would be a good idea to understand the main packages that form part of JDOM2 and the functionalities that each of the packages provide. The first tutorial in the series provides an introduction to the package structure along with important classes in each package. The subsequent tutorials provide examples for each of the key functionalities.

  1. JDOM2 package structure - Introduces the package structure and explains the important classes that form the API
  2. JDOM2 Usage - An introduction to building and using JDOM2 Document.
  3. SAXBuilder Example
  4. SAXBuilder with DTD validation
  5. SAXBuilder with XSD validating - This tutorial explains how create a JDOM2 from an XML using a SAX parser by validating the document using an XSD. The example explains how to validate using an internal XSD as well as an external XSD
  6. SAXBuilder - A discussion on various components of SAXBuilder and ways to configure it
  7. DOMBuilder - A tutorial on building a JDOM2 document from a w3c Document using DOMBuilder.
  8. Building JDOM2 using StAX
  9. Filters
  10. Namespaces
  11. Outputter - In this tutorial we learn how to output JDOM2 as XML, DOM, SAX, StAXEvent and StaxStream
  12. Transforming the JDOM2 document using XSL
  13. Querying a JDOM2 document using Xpath
Acknowledgement - We thankRolf Lear for reviewing the tutorials and giving us a detailed feedback on the pages.


If you like the tutorial then please put in your comments and also ‘like‘ us on facebook or follow us on google.


Java XML - JDOM2 - Packages (2014/9/28 22:10:55)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

In this tutorial we explore the package structure and important classes for Jdom2.

org.jdom2

This package contains the core classes that represent the XML components.

  • Document - Represents the complete XML document. It provides access to the root element and also the docType.
  • DocType - Represents an XML DOCTYPE.
  • Element - Represents an XML element. Has methods to manipulate the child elements, its textual content, attributes and namespaces.
  • Attribute - This represents an XML attribute. There are methods to get and set the value of the attribute and also the namespace. The Attribute has a parent and an AttributeType.
  • Namespace - Represents an XML Namespace.
  • CDATA - This represents an XML CDATA section.
  • Text - This represents an XML Text.
  • Comment - Represents an XML comment. Users can get and set comment text.
  • EntityRef - Represents an XML EnityRef.
  • ProcessingInstruction - Represents an XML Processing Instruction
  • Content - This is an abstract class which is extended by those classes that can be a child of a org.jdom2.Parent class (Element, CDATA, Comment, DocType, EntityRef, ProcessingInstruction, Text)

org.jdom2.filter

These package has filters that allow filtering based on type, name, value or other parameters. It also allows ANDing, ORing and Negating filters. Filters are used in the public <E extends Content> List<E> getContent(final Filter<E> filter) and public <F extends Content> IteratorIterable<F> getDescendants(final Filter<F> filter) methods of the Element class. Filters are also using in the XPath package of JDom2.

org.jdom2.input

This package has the core classes responsible for building the JDOM2 document from DOM, SAX or StAX. The important classes are

  • SAXBuilder - Builds a JDOM document from SAX parser.
  • DOMBuilder - Builds a JDOM document from pre-existing org.w3c.dom.DOM document.
  • StaxEventBuilder - Builds a JDOM document from StAX XMLEventReader
  • StaxStreamBuilder - Builds a JDOM document from StAX XMLStreamReader

org.jdom2.output

These package has classes to ouput the JDOM2 document to various destinations. The main classes are :

  • XMLOutputter - Output a JDOM2 document as a stream of bytes.
  • DOMOutputter - Convert a JDOM2 document into a DOM document. It can also convert various JDOM2 components to its equivalent DOM components
  • SAXOutputter - Convert a JDOM2 document into a stream of SAX events
  • StAXEventOutputter - output a JDOM2 document to an XMLEventWriter.
  • StAXStreamOutputter - Output a JDOM2 document to an XMLStreamWriter.

Other Packages

  • org.jdom2.transform - Helps with XML transformation using JAXP TrAX classes.
  • org.jdom2.xpath - Support for XPath in JDOM2. By default, it uses the Jaxen xpath library

Java XML - Example JDOM2 Usage (2014/9/28 22:10:52)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

Building JDOM2 Document

In this tutorial we look at an example of how to build and navigate through a JDOM2 document from an XML source (in this case, a BBC News "Technology" RSS feed). We first use the org.jdom2.input.SAXBuilder class to create the JDOM2 document from the source (more details and options on the SAXBuilder class will be covered in later tutorials). Once we obtain the JDOM2 Document there are various JDOM2 methods used to access the elements, which will be covered in the next section of this tutorial.

Accessing JDOM2 Components

JDOM2 is a java representation of an XML document. In other words, each XML component is represent as a java object. JDOM2 has convenient methods to access the various components. Here are some of the key use cases (the number in the bracket corresponds to the line number in the example) :

  • Obtaining the root element (25,28) - Root Element is the topmost Element of the document
  • Obtaining the Namespace added by a node (32)
  • Obtaining the contents of a particular node (43) - The node is traveresed recursively till all content is found
  • Obtaining a child of an Element (50)
  • Obtaining all children of an Element(54)
  • Obtaining the first child of a particular type and name e.g. the first text node with name ‘link‘ (62)
  • Obtaining the first child of a particular type and name and from a specified namespace e.g. the first text node with name ‘link‘ from namespace ‘atom‘(70)
  • Obtaining all children with a specific name (75)
  • Iterating through all the descendants of an Element and obtaining Elements with specific name and from a specific Namespace (85)
This is not an exhaustive list of use cases but it gives an idea of what can be achieved. If you have a specific requirement then do post it as acomment and we would be glad to answer it
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.studytrails.xml.jdom;
  
import java.io.IOException;
import java.util.List;
  
import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.util.IteratorIterable;
  
public class CreateJdomFromSax {
  
    private static String xmlSource = "http://feeds.bbci.co.uk/news/technology/rss.xml?edition=int";
  
    public static void main(String[] args) throws JDOMException, IOException {
        // the SAXBuilder is the easiest way to create the JDOM2 objects.
        SAXBuilder jdomBuilder = new SAXBuilder();
  
        // jdomDocument is the JDOM2 Object
        Document jdomDocument = jdomBuilder.build(xmlSource);
  
        // The root element is the root of the document. we print its name
        System.out.println(jdomDocument.getRootElement().getName()); // prints
                                                                        // "rss"
  
        Element rss = jdomDocument.getRootElement();
  
        // The Element class extends Content class which is NamespaceAware. We
        // see what namespace this element introduces.
        System.out.println(rss.getNamespacesIntroduced());
        /*
         * prints [[Namespace: prefix "atom" is mapped to URI
         * "http://www.w3.org/2005/Atom"], [Namespace: prefix "media" is mapped
         * to URI "http://search.yahoo.com/mrss/"]]
         */
  
        // the getContent method traverses through the document and gets all the
        // contents. We print the CType (an enumeration identifying the Content
        // Type), value and class of the Content. we print only the
        // first two values, since this is only an example.
        List<content> rssContents = rss.getContent();
        for (int i = 0; i < 2; i++) {
            Content content = rssContents.get(i);
            System.out.println("CType " + content.getCType());
            System.out.println("Class " + content.getClass());
        }
  
        Element channel = rss.getChild("channel");
  
        // the getChildren method can be used to obtain the children of the
        // element
        List<element> channelChildren = channel.getChildren();
        for (int i = 0; i < 2; i++) {
            Element channelChild = channelChildren.get(i);
            System.out.println(channelChild.getName());// prints ‘title‘ and
                                                        // ‘link‘
        }
  
        // to directly obtain the child node of type Text
        System.out.println(channel.getChildText("link")); // print the first
                                                            // link
  
        // It is also possible to specify the namespace while obtaining the
        // child element. In the statement below we
        // obtain the child with name ‘link‘ but we want that child to be from
        // the atom namespace. We further use the getAttributeValue method to
        // get the value of the attribute of the node
        System.out.println(channel.getChild("link", rss.getNamespace("atom")).getAttributeValue("href"));
        // prints http://feeds.bbci.co.uk/news/technology/rss.xml
  
        // Instead of getting all the children of a node we may want to get all
        // children with a particular name.
        List<element> items = channel.getChildren("item");
        for (int i = 0; i < 2; i++) {
            System.out.println(items.get(i).getChildText("title")); // prints
                                                                    // the first
                                                                    // two
                                                                    // titles
        }
  
        // iterate through all the descendants and get the url of the thumbnails
        // (The thumbnails are declared with namespace media)
        IteratorIterable<content> descendantsOfChannel = channel.getDescendants();
        for (Content descendant : descendantsOfChannel) {
            if (descendant.getCType().equals(Content.CType.Element)) {
                Element element = (Element) descendant;
                if (element.getNamespace().equals(rss.getNamespace("media"))) {
                     System.out.println(element.getAttributeValue("url")); //
                    // prints all urls of all thumbnails within the
                    // ‘media‘ namespace
                }
            }
        }
    }
}
</content></element></element></content>


Java XML - JDOM2 - SAXBuilder Example (2014/9/28 22:10:52)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

In this tutorial we look at how to build a JDOM2 using a SAXBuilder. To understand how SAXBuilder works and how to configure it look at this tutorial. The example below demonstrates the following

  • Building a JDOM2 document using a SAXBuilder.
  • Obtaining the DOCTYPE of the document.
  • Obtaining the root element of the document
  • Obtaining a specific child (specify name) of an element
  • Iterating through the descendants of an Element and printing the values of all elements whose type is not Text or Comment
  • Iterating through the descendants of an Element and printing the elements of type Comment (using a Comment filter)
The example below uses the tomcat web.xml file which can be downloaded fromhere
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.studytrails.xml.jdom;
 
import java.io.File;
import java.io.IOException;
 
import org.jdom2.Comment;
import org.jdom2.Content;
import org.jdom2.Content.CType;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.util.IteratorIterable;
 
public class JdomUsingSAXBuilder {
 
    private static String file1 = "tomcat-web-dtd.xml";
 
    public static void main(String[] args) throws JDOMException, IOException {
 
        // Use a SAX builder
        SAXBuilder builder = new SAXBuilder();
        // build a JDOM2 Document using the SAXBuilder.
        Document jdomDoc = builder.build(new File(file1));
 
        // get the document type
        System.out.println(jdomDoc.getDocType());
 
        //get the root element
        Element web_app = jdomDoc.getRootElement();
        System.out.println(web_app.getName());
         
        // get the first child with the name ‘servlet‘
        Element servlet = web_app.getChild("servlet");
 
        // iterate through the descendants and print non-Text and non-Comment values
        IteratorIterable<Content> contents = web_app.getDescendants();
        while (contents.hasNext()) {
            Content web_app_content = contents.next();
            if (!web_app_content.getCType().equals(CType.Text) && !web_app_content.getCType().equals(CType.Comment)) {
                System.out.println(web_app_content.toString());
            }
        }
 
        // get comments using a Comment filter
        IteratorIterable<Comment> comments = web_app.getDescendants(Filters.comment());
        while (comments.hasNext()) {
            Comment comment = comments.next();
            System.out.println(comment);
        }
 
    }
}


Java XML - JDOM2 - SAXBuilder DTD Validating (2014/9/28 22:10:56)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

In this tutorial we look at how to use SAXBuilder to create a JDOM2 Document such that the SAXBuilder validates the XML using the DTD before creating the JDOM2 document. If you are looking for a way to create JDOM2 Document using the SAXBuilder but without any validation then this tutorial explains just that.

We explain the validation using two XML document. The first XML is invalid and therefore fails the validation step. The second XML is valid.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.studytrails.xml.jdom;
 
import java.io.File;
import java.io.IOException;
 
import org.jdom2.DocType;
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
 
public class JdomUsingSAXBuilderDtdValidating {
    private static String file1 = "tomcat-web-dtd-bad.xml";
    private static String file2 = "tomcat-web-dtd.xml";
 
    public static void main(String[] args) throws JDOMException, IOException {
 
         SAXBuilder builder = new SAXBuilder(XMLReaders.DTDVALIDATING);
         Document jdomDocValidatedFalse = builder.build(new File(file1));
        // throws an error since the XML does not validate. We correct it and
        // then run this again. comment the lines above and run this again.
 
        SAXBuilder builder2 = new SAXBuilder(XMLReaders.DTDVALIDATING);
        Document jdomDocValidatedTrue = builder2.build(new File(file2));
 
        System.out.println(jdomDocValidatedTrue.hasRootElement()); // prints true
         
        DocType docType = jdomDocValidatedTrue.getDocType();
 
        System.out.println(docType.getPublicID());
        // prints -//Sun Microsystems, Inc.//DTD Web Application 2.3//EN
         
        System.out.println(docType.getSystemID());
        // prints http://java.sun.com/dtd/web-app_2_3.dtd
         
 
    }
}

Java XML - JDOM2 - SAXBuilder XSD Validating (2014/9/28 22:10:52)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

In the earlier tutorials we saw how to build a JDOM2 document using SAXBuilder. We also saw how to validate the document using DTD while using the SAXBuilder. In this tutorial we look at how to use the SAXBuilder that validates against an XSD. The example below shows how to use an internally defined XSD. The example after that shows how to define an XSD externally.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.studytrails.xml.jdom;
 
import java.io.File;
import java.io.IOException;
 
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
 
public class JdomUsingSAXBuilderXsdValidating {
 
    private static String file1 = "tomcat-web-xsd-bad.xml";
 
    private static String file2 = "tomcat-web-xsd.xml";
 
    public static void main(String[] args) throws JDOMException, IOException {
        // SAXBuilder builder = new SAXBuilder(XMLReaders.XSDVALIDATING);
        // Document jdomDocValidatedFalse = builder.build(new File(file1));
        // throws an error since the XSD validation fails. comment the lines
        // above and rerun the example
 
        SAXBuilder builder2 = new SAXBuilder(XMLReaders.XSDVALIDATING);
        Document jdomDocValidatedTrue = builder2.build(new File(file2));
 
        System.out.println(builder2.getSAXHandlerFactory().getClass());
        // prints class org.jdom2.input.sax.DefaultSAXHandlerFactory
        System.out.println(builder2.getJDOMFactory().getClass());
        // class org.jdom2.DefaultJDOMFactory
        System.out.println(builder2.getXMLReaderFactory().getClass());
        // class org.jdom2.input.sax.XMLReaders
 
    }
}
Downloadtomcat-web-xsd-bad.xml andtomcat-web-xsd.xml for the example above. Now lets look at an example that shows how to specify an XSD externally.The example below specifies two methods to specify an XSD externally. Downloadcommons-dbcp-pom.xml andmaven-4.0.0.xsd for the example below.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.studytrails.xml.jdom;
 
import java.io.File;
import java.io.IOException;
 
import javax.xml.XMLConstants;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
 
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaderJDOMFactory;
import org.jdom2.input.sax.XMLReaderSchemaFactory;
import org.jdom2.input.sax.XMLReaderXSDFactory;
import org.xml.sax.SAXException;
 
public class JdomUsingSAXBuilderExternalXsdValidating {
 
    private static String file = "commons-dbcp-pom.xml";
    private static String schemaFile = "maven-4.0.0.xsd";
 
    public static void main(String[] args) throws JDOMException, IOException, SAXException {
 
 
         //METHOD 1
          
        // Define a schema factory and a schema
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new File(schemaFile));
         
         
        // create an XMLReaderJDOMFactory by passing the schema
        XMLReaderJDOMFactory factory = new XMLReaderSchemaFactory(schema);
        // create a SAXBuilder using the XMLReaderJDOMFactory
        SAXBuilder sb = new SAXBuilder(factory);
        Document doc = sb.build(new File(file));
        System.out.println(doc.getRootElement().getName());
         
        //METHOD 2
         
        File xsd = new File(schemaFile);
        //Create the XMLReaderJDOMFacotory directly using the schema file instead of ‘Schema‘
        XMLReaderJDOMFactory factory2 = new XMLReaderXSDFactory(schemaFile);
        SAXBuilder sb2 = new SAXBuilder(factory2);
        Document doc2 = sb2.build(new File(file));
        System.out.println(doc2.getRootElement().getName());
 
    }
}

Java XML - JDOM2 - SAXBuilder (2014/9/28 22:10:56)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

The Plot

SAXBuilder provides methods to build JDOM2 Documents using a third party SAX Parser. It has three parts

  • A SAX Parser to parse the XML document. The default Parser is JAXP.
  • A SAX Handler to handle SAX events.
  • A JDOM2 Factory to build the JDOM2 Document
This tutorial introduces the various classes that form part of the SAXBuilder suite. The understanding of these classes is important if you want tocustomize any part of the process. i.e. if you want to validate the XML (DTD, XMLSchema, etc.), if you want to use a different SAX parser or if youwant your own SAXHandler or JDOM2 Factory.

The Actors (Classes)

  • SAXBuilder - This is what the tutorial is all about. The following constructors are available:
    • SAXBuilder() - Uses the default parser, SAX Handler and JDOM2 Factory
    • SAXBuilder(final XMLReaderJDOMFactory readersouce) - Specify a factory to create an XMLReader. Users can also specify any of the three enum singletons : XMLReaders.NONVALIDATING, XMLReaders.DTDVALIDATING and XMLReaders.XSDVALIDATING. What this does is tell the parsers whether it should be validating the XML and if it should use DTD or XSD for validation.
    • SAXBuilder(final XMLReaderJDOMFactory xmlreaderfactory, final SAXHandlerFactory handlerfactory,final JDOMFactory jdomfactory) - Uses custom factories for parsing, SAX event handling and JDOM2 document building
    The most important methods are build(...). When you call the build methods the builder will first get the SAXEngine and then call the build method of the SAXEngine. The build method of the SAXEngine calls the parser to parse the xml. The SAXEngine has access to the SAXHandler and JDOM2 Factory and it starts building the JDOM2 Document as it parses the XML
  • SAXBuilderEngine - This is created by the SAXBuilder and it parses the XML and builds a JDOM2 Document. In high performance applications you can reuse the SAXBuilderEngine multiple times without any parser reconfiguration overhead, and you can create multiple SAXBuilderEngine instances from a single configured SAXBuilder.
  • XMLReaderJDOMFactory - This factory creates the XMLReaders (parsers). The createXMLReader() method creates the XMLReaders. This method is called by the SAXBuilder when it builds the SAXEngine.There are five implementations provided (though you can add your own custom ones if needed). Three of them are singletons of the enum org.jdom2.input.sax.XMLReaders. Lets look at them first
    • XMLReaders.NONVALIDATING, XMLReaders.DTDVALIDATING, XMLReaders.XSDVALIDATING - These are singleton enums for performance and convenience. They use the standard Java JAXP process for identifying and instantiating the XML parser to use, and the different singletons will either perform no XML Validation (just the regular well-formedness checks), DTD Validation, or XMLSchema validation.
    • org.jdom2.input.sax.XMLReaderSchemaFactory - Use this factory if you want to create an XMLReader that uses an external schema for validation. The schema can be any schema that is supported by SAX.
    • org.jdom2.input.sax.XMLReaderXSDFactory - Use this factory if you want to create an XMLReader that uses an external XML Schema for validation
  • SAXHandlerFactory - Instances of this factory are responsible for creating Handlers that handle SAX events (fired by the SAX Parser). Let us look at the various classes that take part in SAX event handling process
    • DefaultSAXHandlerFactory - This is the default implementation of SAXHandlerFactory. It returns the DefaultSAXHandler which is just a wrapper over org.jdom2.input.sax.SAXHandler
    • SAXHandler - This class is responsible for handling SAX events produced by the XMLReader. It also takes in the JDOMFactory. If the XMLReader supports document locator for line and column number then the SAXHandler will supply that to the JDOMFactory
  • JDOMFactory- This is the last piece of the puzzle. Instances of this factory create the JDOM2 Classes that are part of the JDOM2 structure. The important classes are :
    • org.jdom2.DefaultJDOMFactory - This creates the standard JDOM2 classes.
    • org.jdom2.LocatedJDOMFactory - This creates the JDOM2 classes that have implemented the org.jdom2.located.Located interface
    • org.jdom2.SlimJDOMFactory - This creates the JDOM2 content that occupies less memory by reusing string instances


Java XML - JDOM2 - DOMBuilder (2014/9/28 22:10:54)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

Buliding JDOM2 documents from w3c DOM

JDOM2 provides a DOMBuilder that can be used to build a JDOM2 Document from a org.w3c.dom.Document. If there are namespace declarations in the xml document then make sure that while parsing the XML document the setNamespaceAware method of the DocumentBuilderFactory is set to true. Before we look at an example note that it is recommended to use a SAXBuilder to build a JDOM2 Document instead of a DOMBuilder since there is no reason to have both the DOM and JDOM2 Document in memory. Lets look at an example now.

package com.studytrails.xml.jdom;import java.io.IOException;import java.util.List;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.jdom2.Document;import org.jdom2.Element;import org.jdom2.input.DOMBuilder;import org.xml.sax.SAXException;public class CreateJdomFromDom {	private static String xmlSource = "http://feeds.bbci.co.uk/news/technology/rss.xml?edition=int";	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {		// create the w3c DOM document from which JDOM is to be created		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();		// we are interested in making it namespace aware.		factory.setNamespaceAware(true);		DocumentBuilder dombuilder = factory.newDocumentBuilder();		org.w3c.dom.Document w3cDocument = dombuilder.parse(xmlSource);		// w3cDocument is the w3c DOM object. we now build the JDOM2 object		// the DOMBuilder uses the DefaultJDOMFactory to create the JDOM2		// objects.		DOMBuilder jdomBuilder = new DOMBuilder();		// jdomDocument is the JDOM2 Object		Document jdomDocument = jdomBuilder.build(w3cDocument);		// The root element is the root of the document. we print its name		System.out.println(jdomDocument.getRootElement().getName()); // prints																		// "rss"			}}

Java XML - JDOM2 - StAXBuilder (2014/9/28 22:10:55)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

In the previous examples we saw how to bulid a JDOM2 document from w3c Document. We also saw how to build a JDOM2 Document using a SAXBuilder. In this example we look at how to create a JDOM2 document using a StAXEventBuilder or a StAXStreamBuilder.

StAXEventBuilder

StAXEventBuilder builds a JDOM2 document using a StAX based XMLEventReader. We first create an XMLInputFactory. We then use the factory to create an XMLEventReader by passing the XML file. The XMLEventReader is then passed to the StAXEventBuilder. Note that StAXEvenBuilder has no control over the validation process and therefore to create a validating builder set the appropriate property on the XMLInputFactory. Here‘s an example. The XML file can be downloaded from here

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.studytrails.xml.jdom;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
 
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
 
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.StAXEventBuilder;
 
public class JdomUsingXMLEventReader {
 
    public static void main(String[] args) throws FileNotFoundException, XMLStreamException, JDOMException {
        XMLInputFactory factory = XMLInputFactory.newFactory();
 
        XMLEventReader reader = factory.createXMLEventReader(new FileReader("bbc.xml"));
 
        StAXEventBuilder builder = new StAXEventBuilder();
        Document jdomDoc = builder.build(reader);
        System.out.println(jdomDoc.getRootElement().getName()); // prints "rss"
        System.out.println(jdomDoc.getRootElement().getNamespacesIntroduced().get(1).getURI()); // prints "http://search.yahoo.com/mrss/"
 
    }
}

StAXStreamBuilder

StAXStreamBuilder builds a JDOM2 document from a StAX based XMLStreamReader. For JDOM2 XMLStreamReader is more efficient then XMLEventReader and should be the first choice. Here‘s an example

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.studytrails.xml.jdom;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
 
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
 
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.StAXStreamBuilder;
 
public class JdomUsingXMLStreamReader {
 
    public static void main(String[] args) throws FileNotFoundException, XMLStreamException, JDOMException {
        XMLInputFactory factory = XMLInputFactory.newFactory();
        XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("bbc.xml"));
 
        StAXStreamBuilder builder = new StAXStreamBuilder();
        Document jdomDoc = builder.build(reader);
        System.out.println(jdomDoc.getRootElement().getName());  // prints "rss"
        System.out.println(jdomDoc.getRootElement().getNamespacesIntroduced().get(1).getURI());// prints "http://search.yahoo.com/mrss/"
    }
}


Java XML - JDOM2 - Filters (2014/9/28 22:11:01)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

JDOM2 has three methods that accepts Filters while obtaining data. The three methods are

  • <E extends Content> List<E> getContent(Filter<E> filter);
  • <E extends Content> List<E> removeContent(Filter<E> filter);
  • <E extends Content> IteratorIterable<E> getDescendants(Filter<E> filter);
Filters are also extensively used in the JDOM2 XPath API, especially to ‘coerce the xpath result data in to the generic-typed results‘. Seethis tutorial on xpath to understand how Filters are used in the JDOM2 XPath API.
The main classes are :
  1. org.jdom2.filter.AbstractFilter - Contains partial implementation of org.jdom2.filter.Filter
  2. org.jdom2.filter.ContentFilter - Filters various JDOM2 objects such as ELEMENT, CDATA, TEXT, COMMENT, PI, ENTITYREF, DOCUMENT and DOCTYPE. It can also filter a group of Objects such as both ELEMENT and COMMENT.
  3. org.jdom2.filter.ElementFilter - Allows org.jdom2.Element
  4. org.jdom2.filter.AttributeFilter - Allows org.jdom2.Attribute
  5. org.jdom2.filter.Filters - Factory class to create other filters. Most users will use this class to create filters. The most important methods of this class are :
    • public static final Filter<Attribute> attribute() - matches Attribute
    • public static final Filter<Attribute> attribute(String name) - matches Attribute with a specific name.
    • public static final Filter<Attribute> attribute(String name, Namespace ns) - matches Attribute with a specific name in a specific namespace.
    • public static final Filter<Attribute> attribute(Namespace ns) - matches Attribute within a specified namespace.
    • public static final Filter<Comment> comment() - matches Comment.
    • public static final Filter<CDATA> cdata() - matches CDATA.
    • public static final Filter<DocType> doctype() - matches DocType.
    • public static final Filter<EntityRef> entityref() - matches EntityRef.
    • public static final Filter<Element> element() - matches Element.
    • public static final Filter<Document> document() - matches Document.
    • public static final Filter<Element> element(String name) - matches Element with a specified name.
    • public static final Filter<Element> element(String name, Namespace ns) - matches Element with a specified name and namespace.
    • public static final Filter<Element> element(Namespace ns) - .matches all Elements within a specified namespace
    • public static final Filter<ProcessingInstruction> processinginstruction() - matches Processing Instruction.
    • public static final Filter<Text> text() - matches Text (including CDATA).
    • public static final Filter<Text> textOnly() - matches Text (exclusing CDATA).
    • public static final Filter<Boolean> fboolean() - matches Boolean data.
    • public static final Filter<String> fstring() - matches String data.
    • public static final Filter<Double> fdouble() - matches Double data.
    • public static final <F> Filter<F> fclass(Class<F> clazz) - matches a specified class.
    • public static final Filter<Object> fpassthrough() - matches everything, does not filterFd.
The following operations can be performed on a filter
  • public Filter<? extends Object> negate() - returns Objects NOT matched by the filter.
  • public Filter<? extends Object> or(Filter<?> filter) - returns Objects that are passed by any one of the filters
  • public Filter<T> and(Filter<?> filter) - returns objects matched by both the filters.
  • public <R> Filter<R> refine(Filter<R> filter) - Similar to the ‘and‘ filter but the generic type of the result is taken from the generic type of the input
The class diagramClass Diagram
Lets look at an example
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.studytrails.xml.jdom;
  
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
 
import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Text;
import org.jdom2.filter.ContentFilter;
import org.jdom2.filter.Filter;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.util.IteratorIterable;
  
public class FilterJdom2 {
    private static String xmlSource = "http://feeds.bbci.co.uk/news/technology/rss.xml?edition=int";
  
    public static void main(String[] args) throws JDOMException, IOException {
        SAXBuilder jdomBuilder = new SAXBuilder();
        Document jdomDocument = jdomBuilder.build(xmlSource);
  
        Element rss = jdomDocument.getRootElement();
        Element channel = rss.getChild("channel");
  
        Element title = channel.getChild("title");
  
        // Content Filter
        ContentFilter filter = new ContentFilter(ContentFilter.PI);
        List<content> cDataContents = jdomDocument.getContent(filter);
        Iterator<content> cDataIterator = cDataContents.iterator();
        while (cDataIterator.hasNext()) {
            Content cdata = http://www.mamicode.com/cDataIterator.next();
            // System.out.println(cdata.getCType());
            // System.out.println(cdata.getValue());
        }
  
        // Text Filter
        Filter<text> textFilter = Filters.text();
        IteratorIterable<text> channelTextList = channel.getDescendants(textFilter);
        while (channelTextList.hasNext()) {
            Text channelText = channelTextList.next();
            // System.out.println(channelText.getValue());
        }
  
        // or filter
        Filter<element> filters = (Filter<element>) Filters.element("thumbnail", rss.getNamespace("media")).or(Filters.element("link"));
        IteratorIterable<element> thumbnailsAndLinks = channel.getDescendants(filters);
        while (thumbnailsAndLinks.hasNext()) {
            Element thumbnailorLink = thumbnailsAndLinks.next();
            // System.out.println(thumbnailorLink.getName());
        }
  
        // negate filter
        Filter<element> negateFilter = (Filter<element>) Filters.element("link").negate().and(Filters.text().negate());
        IteratorIterable<element> nonLinkElements = channel.getDescendants(negateFilter);
        while (nonLinkElements.hasNext()) {
            Element nonLinkElement = nonLinkElements.next();
            System.out.println(nonLinkElement.getName());
        }
  
    }
}
</element></element></element></element></element></element></text></text></content></content>


Java XML - JDOM2 - Namespaces (2014/9/28 22:10:55)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

JDOM2 handles namespaces very well. However, there are three areas where confusion may arise while using namespaces. In this tutorial we look at them.

Creating new elements

While creating new elements in JDOM2, it is possible to pass the namespace to which the element should belong. However, the namespace only applies to the Element and not its children. i.e. the namespace assignment does not cascade. Here‘s an example

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.studytrails.xml.jdom;
 
import org.jdom2.Attribute;
import org.jdom2.Comment;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
 
public class NewElementAndNamespace {
    private static String xmlSource = "http://feeds.bbci.co.uk/news/technology/rss.xml?edition=int";
 
    public static void main(String[] args) {
 
        Namespace namespace = Namespace.getNamespace("p", "http://namespaceuri");
        // create the jdom
        Document jdomDoc = new Document();
        // create root element
        Element rootElement = new Element("Root", namespace);
        jdomDoc.setRootElement(rootElement);
 
        // add a comment
        Comment comment = new Comment("This is a comment");
        rootElement.addContent(comment);
 
        // add child
        Element child1 = new Element("child1", namespace);
        child1.addContent("This is child 1");
 
        // add child 2
        Element child2 = new Element("child2");
        child2.addContent("This is child 2");
 
        // add attribute
        Attribute attr1 = new Attribute("key1", "value1");
        child1.setAttribute(attr1);
        rootElement.addContent(child1);
        rootElement.addContent(child2);
 
        // Output as XML
        // create XMLOutputter
        XMLOutputter xml = new XMLOutputter();
        // we want to format the xml. This is used only for demonstration.
        // pretty formatting adds extra spaces and is generally not required.
        xml.setFormat(Format.getPrettyFormat());
        System.out.println(xml.outputString(jdomDoc));
    }
}
The output is
?
1
2
3
4
5
6
<!--?xml version="1.0" encoding="UTF-8"?-->
<p:root xmlns:p="http://namespaceuri">
  <!--This is a comment-->
  <p:child1 key1="value1">This is child 1</p:child1>
  <child2>This is child 2</child2>
</p:root>
Notice how the namespace prefix is applied only to only child.

Searching for a child which is in a namespace

In the next example we read the XML created in the example above. (test.xml) we then search for a child named ‘child1‘, first without specifying a namespace and then after specifying a namespace. In the first case it is not able to find the child, in the second case it does

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.studytrails.xml.jdom;
 
import java.io.IOException;
 
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.input.SAXBuilder;
 
public class GetChildInANamespace {
    private static String xmlTestFile = "test.xml";
 
    public static void main(String[] args) throws JDOMException, IOException {
        SAXBuilder jdomBuilder = new SAXBuilder();
        Document jdomDocument = jdomBuilder.build(xmlTestFile);
 
        // the root element
        Element root = jdomDocument.getRootElement();
 
        // lets search for a child named child1
 
        System.out.println(root.getChild("child1"));
        // prints null
 
        System.out.println(root.getChild("child1", Namespace.getNamespace("p", "http://namespaceuri")));
        // prints [Element: <p:child1 [Namespace: http://namespaceuri]/>]
    }
}

XPath and Namespace

JDOM2 XPath allows searching for an element with a specific Namespace. If an element is specified in a new Namespace then pass that JDOM2 Namespace object when searching for that element. If the XML defines a new default Namespace then create a new ‘dummy‘ JDOM2 Namespace object with any prefix and the default Namespace URI specified in the XML. Access elements in the XML using the prefix of the ‘dummy‘ JDOM2 Namespace object. . See example for more details. The example uses the following xml

?
1
2
3
4
5
6
<!--?xml version="1.0" encoding="UTF-8"?-->
<root xmlns="http://nondefaulnamespace" xmlns:p="http//anothernamespace">
    <!--This is a comment -->
    <p:child1>This is child 1</p:child1>
    <child2>This is child 2</child2>
</root>
The Example
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.studytrails.xml.jdom;
 
import java.io.IOException;
 
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
 
public class XpathAndNamespace {
    private static String xmlTestFile = "test2.xml";
 
    public static void main(String[] args) throws JDOMException, IOException {
        // read the XML into a JDOM2 document.
        SAXBuilder jdomBuilder = new SAXBuilder();
        Document jdomDocument = jdomBuilder.build(xmlTestFile);
 
        XPathFactory xFactory = XPathFactory.instance();
 
        XPathExpression<element> expr = xFactory.compile("//child2", Filters.element());
        Element child2 = expr.evaluateFirst(jdomDocument);
        System.out.println(child2);
        // prints null
 
        // we create a dummy namespace prefix that points to the default
        // namespace and then access the element using that namespace
        Namespace defaultNs = Namespace.getNamespace("a", "http://nondefaulnamespace");
        XPathExpression<Element> expr2 = xFactory.compile("//a:child2", Filters.element(), null, defaultNs);
        child2 = expr2.evaluateFirst(jdomDocument);
        System.out.println(child2);
        // prints [Element: <child2 [Namespace: http://nondefaulnamespace]/>]
 
        // search for a child from another namespace
        Namespace anotherNS = Namespace.getNamespace("p", "http//anothernamespace");
        XPathExpression<Element>> expr3 = xFactory.compile("//p:child1", Filters.element(), null, anotherNS);
        Element child1 = expr3.evaluateFirst(jdomDocument);
        System.out.println(child1);
        // prints [Element: <p:child1 [Namespace: http//anothernamespace]/>]
    }
}
 
 
 
 
 
 
</element>


Java XML - JDOM2 - Outputter (2014/9/28 22:10:57)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

Introduction

In the earlier tutorials we looked at how to create a JDOM2 document from SAX ,DOM and StAX. In this tutorial we learn how to output JDOM2 as XML, DOM, SAX, StAXEvent and StaxStream. Lets look at the important classes

Important Classes

  • XMLOutputter - This is probably the most useful outputter. It outputs the JDOM2 document as a stream of byes that can be written to a file. In other words, to create an XML file from JDOM2 document use this class. The most useful methods is public final void output(Document doc, OutputStream out). The encoding of the writer should match the encoding of the Format object of the Outputter. The conversion can be customized by using a custom XMLOutputProcessor
  • DOMOutputter - Outputs a JDOM2 document as a w3c DOM Document. It can be configured by passing in three types of objects - DOMAdapter, Format and DOMOutputProcessor. A DOMAdapter is an interface whose implementation interfaces with a DOMParser to create DOM objects. The default implementation is JAXPDOMAdapter. The DOMOutputProcessor is the main class responsible for the conversion. The important method is public final void output(Document doc, XMLStreamWriter out) throws XMLStreamException. An Element can also be passed instead of a Document
  • SAXOutputter - Outputs a JDOM2 document as a stream of SAX2 Events. It takes in a ContentHandler to process the SAX events. It can also be configured using an ErrorHandler, DTDHandler, EntityResolver, LexicalHandler and DeclHandler. It also uses a SAXOutputProcessor that does the bulk of the processing. The most useful constructor is public SAXOutputter(ContentHandler contentHandler) and the the output method is public final void output(Document doc, XMLStreamWriter out) throws XMLStreamException
  • StAXEventOutputter Outputs the JDOM2 document as a series of events that can be read by an XMLEventConsumer. The default processor to process the conversion is DefaultStAXEventProcessor. This can be customized, if required. The most useful method is public final void output(Document doc, XMLEventConsumer out) throws XMLStreamExceptionThe format can also be specified. The following formats are available :
    • for pretty printing - Format.getPrettyFormat()
    • for whitespace-normalized output - Format.getCompactFormat()
    • for unmodified-format output - Format.getRawFormat()
  • StAXStreamOutputter - Outputs the JDOM2 document as a stream that is handled by XMLStreamWriter. Here‘s how the main method looks public final void output(Element element, XMLStreamWriter out) throws XMLStreamException. The default processor is DefaultStAXStreamProcessor
  • StAXStreamReader - Outputs the JDOM2 document as an XMLStreamReader.

Example

Now lets see the outputters in action

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.studytrails.xml.jdom;
 
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.XMLEventConsumer;
 
import org.jdom2.Attribute;
import org.jdom2.Comment;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.output.DOMOutputter;
import org.jdom2.output.Format;
import org.jdom2.output.SAXOutputter;
import org.jdom2.output.StAXEventOutputter;
import org.jdom2.output.XMLOutputter;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
public class JDomOutputterExamples {
 
    public static void main(String[] args) throws JDOMException, XMLStreamException {
 
        // create the jdom
        Document jdomDoc = new Document();
        // create root element
        Element rootElement = new Element("Root");
        jdomDoc.setRootElement(rootElement);
 
        // add a comment
        Comment comment = new Comment("This is a comment");
        rootElement.addContent(comment);
 
        // add child
        Element child1 = new Element("child");
        child1.addContent("This is child 1");
         
        // add attribute
        Attribute attr1 = new Attribute("key1", "value1");
        child1.setAttribute(attr1);
        rootElement.addContent(child1);
 
        // Output as XML
        // create XMLOutputter
        XMLOutputter xml = new XMLOutputter();
        // we want to format the xml. This is used only for demonstration. pretty formatting adds extra spaces and is generally not required.
        xml.setFormat(Format.getPrettyFormat());
        System.out.println(xml.outputString(jdomDoc));
         
 
        // Output the JDOM2 document as a w3c Document
        // create the DOM Outputter
        DOMOutputter domOutputer = new DOMOutputter();
        // create the w3c Document from the JDOM2 Document
        org.w3c.dom.Document dom = domOutputer.output(jdomDoc);
        System.out.println(dom.getNodeName());
 
        //  we iterate through the w3c Document and print the elements
        org.w3c.dom.Element rootElementDom = dom.getDocumentElement();
        System.out.println(rootElementDom.getNodeName());
        NodeList children = rootElementDom.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            System.out.println("Node Name-->" + child.getNodeName());
            System.out.println("Node value-->" + child.getNodeValue());
            System.out.println("Node Attributes-->" + child.getAttributes());
        }
 
        // Output the JDOM2 as SAX events. Pass in the ContentHandler that will handle the events.
        SAXOutputter saxOutputer = new SAXOutputter(new myContentHandler());
        saxOutputer.output(jdomDoc);
 
        // Output as StaxEvents. Pass in a custom XMLEventConsumer.
        StAXEventOutputter staxOutputter = new StAXEventOutputter();
        staxOutputter.output(jdomDoc, new XMLEventConsumer() {
 
            @Override
            public void add(XMLEvent event) throws XMLStreamException {
                int eventType = event.getEventType();
                if (XMLEvent.COMMENT == eventType) {
                    System.out.println(event.toString());
                }
                if (XMLEvent.START_ELEMENT == eventType) {
                    System.out.println(event.asStartElement().getName());
                }
 
            }
        });
    }
 
    public static class myContentHandler extends DefaultHandler {
        @Override
        public void startDocument() throws SAXException {
            System.out.println("Start Doc");
            super.startDocument();
        }
 
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            System.out.println("Start " + localName);
            super.startElement(uri, localName, qName, attributes);
        }
    }
 
}

Java XML - JDOM2 - XSLTransformation (2014/9/28 22:10:54)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

JDOM2 has classes that perform XSL transformation of the JDOM2 document. The input to the transformation is the JDOM2 document and an XML stylesheet and the output is whatever transformation the stylesheet specifies. In the example below we look at JDOM2 to do HTML transformation. By default, JDOM2 uses the JAXP TrAX classes for transformation. The important classes are :

  • JDOMSource - This class holds the input for the transformation. It can be a Document, node or list of nodes.
  • JDOMResult - This class holds the result of the transformation. It is generally a list of nodes or a JDOM2 document. The result tree may not be a well formed XML document.
  • XSLTranfomer - The class that wraps the transformation. It uses the JAXP TrAX classes for actual transformation. The javax.xml.transform.TransformerFactory java system property determines which XSLT engine is to be used. As specified in the code documentation this could be
    • Saxon 6.x: com.icl.saxon.TransformerFactoryImpl
    • Saxon 7.x: net.sf.saxon.TransformerFactoryImpl
    • Xalan: org.apache.xalan.processor.TransformerFactoryImpl
    • jd.xslt: jd.xml.xslt.trax.TransformerFactoryImpl
    • Oracle: oracle.xml.jaxp.JXSAXTransformerFactory
Lets look at an example of a transformation.The source XML can be downloaded fromhere and the xsl can be downloaded fromhere.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.studytrails.xml.jdom;
 
import java.io.IOException;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamSource;
 
import org.jdom2.Document;
import org.jdom2.input.DOMBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jdom2.transform.JDOMResult;
import org.jdom2.transform.JDOMSource;
import org.xml.sax.SAXException;
 
public class JdomTransformationExample {
 
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerFactoryConfigurationError,
            TransformerException {
        //  read the XML to a JDOM2 document
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder dombuilder = factory.newDocumentBuilder();
 
        org.w3c.dom.Document w3cDocument = dombuilder.parse("bbc.xml");
        DOMBuilder jdomBuilder = new DOMBuilder();
        Document jdomDocument = jdomBuilder.build(w3cDocument);
 
        // create the JDOMSource from JDOM2 document
        JDOMSource source = new JDOMSource(jdomDocument);
         
        // create the transformer
        Transformer transformer = TransformerFactory.newInstance().newTransformer(new StreamSource("bbc.xsl"));
         
        // create the JDOMResult object
        JDOMResult out = new JDOMResult();
         
        // perform the transformation
        transformer.transform(source, out);
 
        XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
        System.out.println(outputter.outputString(out.getDocument()));
    }
}


Java XML - JDOM2 - XPath (2014/9/28 22:10:58)

<iframe width="336" height="280" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;" src=""></iframe>

Xpath is a query language specification that is used to query an XML path. It provides a language that helps in retrieving specific nodes of an XML document using a query syntax. This tutorial does not explain XPath and assumes that the user is aware of XPath. What we explain here is how to use Xpath to query a JDOM2 document. The default implementation for JDOM2 is jaxen. To run the below examples jaxen needs to be in the classpath. To query the JDOM2 document first compile an XPathExpression using an XPathFactory. Use the expression to then evaluate the JDOM2 document.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.studytrails.xml.jdom;
  
import java.io.IOException;
import java.util.List;
 
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
  
public class XPathExample2 {
    private static String xmlSource = "http://feeds.bbci.co.uk/news/technology/rss.xml?edition=int";
  
    public static void main(String[] args) throws JDOMException, IOException {
  
        // read the XML into a JDOM2 document.
        SAXBuilder jdomBuilder = new SAXBuilder();
        Document jdomDocument = jdomBuilder.build(xmlSource);
  
        // use the default implementation
        XPathFactory xFactory = XPathFactory.instance();
        // System.out.println(xFactory.getClass());
  
        // select all links
        XPathExpression<Element> expr = xFactory.compile("//link", Filters.element());
        List<Element> links = expr.evaluate(jdomDocument);
        for (Element linkElement : links) {
            System.out.println(linkElement.getValue());
        }
  
        // select all links in image element
        expr = xFactory.compile("//image/link", Filters.element());
        List<Element> links2 = expr.evaluate(jdomDocument);
        for (Element linkElement : links2) {
            System.out.println(linkElement.getValue());
        }
  
        // get the media namespace
        Namespace media = jdomDocument.getRootElement().getNamespace("media");
        // find all thumbnail elements from the media namespace where the
        // attribute widht has a value > 60
        expr = xFactory.compile("//media:thumbnail[@width>60.00]", Filters.element(), null, media);
        // find the first element in the document and get its attribute named ‘url‘
        System.out.println(expr.evaluateFirst(jdomDocument).getAttributeValue("url"));
                 
  
        // find the child element of channel whose name is title. find the
        // descendant of item with name title.
        Element firstTitle = xFactory.compile("//channel/child::item/descendant::title", Filters.element()).evaluateFirst(jdomDocument);
        System.out.println(firstTitle.getValue());
  
    }
  
}


来自为知笔记(Wiz)


Java XML - JDOM2