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 whole inner text of the parameters element. e.g.
name = "JET"
maxInstances = 5
parameters = "<a>1</a><b><b1>test1</b1><b2>test2</b2></b>"
Ultimately the parameters block can contain any well formed XML.
The following code works for name and maxInstances but not 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've tried looking at solutions based on the following ideas but can't find something appropriate.
Is there a different type I can use for the parameters object representing the XML Tree that I could parse to produce a string? e.g.
@XmlElement(name="parameters")
private XmlNodeObject parametersNode;
public String getParameters() {
    // Collapse node to single line of text
    return innerText;
}
Or do I need to use some different kind of annotation?
@XmlSpecialAnnotation(...)
@XmlElement(name="parameters")
private String parameters;
Do I need to switch to a different style of parser? Is it a good/bad idea to use two styles of parser?
You can use the @XmlAnyElement annotation as described by bmargulies.  To map to the object model in your question you can leverage a DOMHandler.
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);
    }
}
                        The closest you could come is to map 'parameters' to a DOM tree, by declaring the variable to be org.w3c.dom.Node. (Actually, declaring a JAXBElement).
For details, see http://jaxb.java.net/guide/Avoid_strong_databinding.html. That gives you the schema-first prescription, you can see how to start from java by running that schema through xsd2java and looking at the output.
To get a string you'll have to serialize from the DOM.
Or, even more specifically:
this page here describes xsd:any processing, and thus
  @XmlAnyElement
  public List<Element> getParameters();
Where Element is the DOM interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With