Using JAXB to retrieve the inner text of an XML element

Problem

Given the following XML configuration file:

<main> <name>JET</name> <maxInstances>5</maxInstances> <parameters> <a>1</a> <b> <b1>test1</b1> <b2>test2</b2> </b> </parameters> </main> 

I need to extract the value of the name and maxInstances elements, and then the entire inner text of the parameter element. eg.

 name = "JET" maxInstances = 5 parameters = "<a>1</a><b><b1>test1</b1><b2>test2</b2></b>" 

Ultimately, a parameter block can contain any well-formed XML.

Attempt to solve

The following code works for the name and maxInstances, but not for the parameters:

 @XmlRootElement(name="main") public class Main { @XmlElement(name="name", required="true") private String name; @XmlElement(name="maxInstances", required="true") private Integer maxInstances; @XmlElement(name="parameters") private String parameters; } 

I tried to search for solutions based on the following ideas, but I can not find something suitable.

Is there any other type that I can use for a parameter object representing an XML tree that I could parse to create a string? eg.

 @XmlElement(name="parameters") private XmlNodeObject parametersNode; public String getParameters() { // Collapse node to single line of text return innerText; } 

Or do I need to use several different annotations?

 @XmlSpecialAnnotation(...) @XmlElement(name="parameters") private String parameters; 

Do I need to switch to a different parser style? Is it a good / bad idea to use two parser styles?

+7
source share
2 answers

Closest you can find the β€œparameters” in the DOM tree by declaring the variable org.w3c.dom.Node . (Actually, declaring JAXBElement).

See http://jaxb.java.net/guide/Avoid_strong_databinding.html for more details. This gives you the first recipe for the circuit; you can see how to start with java by running this circuit through xsd2java and looking at the result.

To get the string, you have to serialize from the DOM.

Or more specifically:

this page here describes xsd: any processing and therefore

  @XmlAnyElement public List<Element> getParameters(); 

Where Element is the DOM interface.

+6
source

You can use the @XmlAnyElement annotation as described in bmargulies . To map the object model to your question, you can use DOMHandler .

the main

 import javax.xml.bind.annotation.*; @XmlRootElement(name="main") @XmlAccessorType(XmlAccessType.FIELD) public class Main { private String name; private Integer maxInstances; @XmlAnyElement(value=ParameterHandler.class) private String parameters; } 

ParameterHandler

 import java.io.*; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.annotation.DomHandler; import javax.xml.transform.Source; import javax.xml.transform.stream.*; public class ParameterHandler implements DomHandler<String, StreamResult> { private static final String PARAMETERS_START_TAG = "<parameters>"; private static final String PARAMETERS_END_TAG = "</parameters>"; private StringWriter xmlWriter = new StringWriter(); public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) { return new StreamResult(xmlWriter); } public String getElement(StreamResult rt) { String xml = rt.getWriter().toString(); int beginIndex = xml.indexOf(PARAMETERS_START_TAG) + PARAMETERS_START_TAG.length(); int endIndex = xml.indexOf(PARAMETERS_END_TAG); return xml.substring(beginIndex, endIndex); } public Source marshal(String n, ValidationEventHandler errorHandler) { try { String xml = PARAMETERS_START_TAG + n.trim() + PARAMETERS_END_TAG; StringReader xmlReader = new StringReader(xml); return new StreamSource(xmlReader); } catch(Exception e) { throw new RuntimeException(e); } } } 

Demo

 import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Main.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); Main main = (Main) unmarshaller.unmarshal(new File("input.xml")); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(main, System.out); } } 
+10
source

All Articles