JAXB marshalling object having property of type Li

2019-07-20 08:15发布

问题:

Following file TPAExtensionsType.java I have generated from a XSD file.

TPAExtensionsType.java

/* 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="TPA_Extensions_Type">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;any processContents='skip' maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */ 
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TPA_Extensions_Type", propOrder = {
    "any"
})
@XmlRootElement 
public class TPAExtensionsType {

    @XmlAnyElement
    protected List<Element> any;

    /**
     * Gets the value of the any property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the any property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getAny().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Element }
     * 
     * 
     */
    public List<Element> getAny() {
    if (any == null) {
        any = new ArrayList<Element>();
    }
    return this.any;
    }

}

Following is the standalone application to marshall the above object to XML.

TestUtil.java

public class TestUtil {
    public static void main(String[] args) {
        TPAExtensionsType tpaExtensions = new TPAExtensionsType();
        Element consumerInfo = new DOMElement("ConsumerInfo");
        consumerInfo.setNodeValue("Some Info");
        tpaExtensions.getAny().add(consumerInfo);

        StringWriter sw  = new StringWriter();
        JAXBContext context;
        try {
            context = JAXBContext.newInstance(TPAExtensionsType.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.marshal(tpaExtensions, sw);
            System.out.println(sw.toString());
        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }
}

Following is the output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tpaExtensionsType xmlns="SOME_NAMESPACE_ HERE">
    <ConsumerInfo xmlns="" xmlns:ns2="SOME_NAMESPACE_ HERE"/>
</tpaExtensionsType>

Problem I am facing:

The node ConsumerInfo has been created but its value is not visible in the generated XML though I have set its value in my standalone application above.Can anybody please help me getting this fixed and what is causing this problem?

回答1:

Quoting the DOM spec on nodeValue(emphasis mine):

The value of this node, depending on its type; see the table above. When it is defined to be null, setting it has no effect.

If you scroll up a bit, you'll see a table where it mentions that Element type nodes are defined with a null nodeValue. I guess that's why it doesn't show up in your XML, because setting it has no effect.

Maybe you could use Node.setTextContent(String textContent)?

Document doc = DocumentBuilderFactory.newInstance()
                  .newDocumentBuilder().newDocument();
Element consumerInfo = doc.createElement("consumerInfo");
consumerInfo.setTextContent("some info");
doc.appendChild(consumerInfo);
TPAExtensionsType tp = new TPAExtensionsType();
tp.getAny().add((Element) doc.getFirstChild());

JAXBContext jc = JAXBContext.newInstance(TPAExtensionsType.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(tp, System.out); 

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tpaExtensionsType>
    <consumerInfo>some info</consumerInfo>
</tpaExtensionsType>