Is there a way not to use XMLRootElement in jaxb2marshaller?

Asked 1 years ago, Updated 1 years ago, 93 views

Is there a way to specify the root element without using XMLRootElement in jaxb2marshaller?

I want to give the root element various depending on the conditions at the controller end

XMLRootElement does not give VO any other conditions, and only one comes out.

jaxb2marshaller xmlrootelement xml

2022-09-22 21:58

2 Answers

When Marshaling/Unmashaling with XML, you can create an ObjectFactory that determines the Root Element.

ObjectFactory.java

// ObjectFactory should be annotated with @XmlRegistry.
// There is no separate inheritance, but it is not possible to provide createXXX functions
// That's the purpose.
@XmlRegistry
public class ObjectFactory {
    // An element defined to enable Root on the XML schema
    // Define the QName as follows:
    // For convenience, I used ns://namespace
    // You specified the names of two type elements that are Root candidates.
    private final static QName someRootAltNum1 = 
        new QName("ns://namespace","some-root-alt-A");
    private final static QName someRootAltNum2 = 
        new QName("ns://namespace","some-root-alt-One");

    public ObjectFactory() {
    }

    // AltNum1 annotated with @XmlType.
    // This is the case when defined as Type in the XML schema.
    // This means that it is not defined as @XmlRootElement.
    public AltNum1Type createAltNum1() {
       return new AltNum1();
    }

    // AltNum2 is another @XmlType.
    // The description is the same as AltNum1.
    public AltNum2Type createAltNum2() {
        return new AltNum2();
    }

    // If the Root Element candidate named some-root-alt-A
    // If specified as AltNum1Type, write:
    // @XmlElementDecl declares the element type information.
    // The function's factor corresponds to the type specified in some-root-alt-A
    // Specifies the Java class (using @XmlType).
    // In this case, some-root-alt-A does not have a separate Java class 
    // Some-root-alt-A is mapped to a Java class corresponding to that XML type.
    // 
    @XmlElementDecl(namespace = "ns://namespace",  name="some-root-alt-A"
    public JAXBElement<AltNum1Type> createSomeRootAltA(AltNum1Type value) {
        return new JAXBElement<AddressType>(someRootAltNum1 ,AltNum1Type.class,null,value);
    }

    // All other root candidate elements must be completed.
    ...


The key is the part that corresponds to the description in createSomeRootAltA above.

In fact, ObjectFactory is automatically created when you create an XML schema first and then use the JAXB compiler (xjc).

And there's a way to mark @XmlSchema on the package that corresponds to Class and XML, or just use it.

package-info.java

@XmlSchema(namespace = "ns://namespace", elementFormDefault = XmlNsForm.QUALIFIED)
package org.example.xml;

import javax.xml.bind.annotation.*;

When using it, you can just use it as follows. If it does not violate the rules of the XML schema, it can be converted.

Example.java

 public static void main(String[] args) throws Exception {
        // Next, in the package-info.java of org.example.xml package,
        // @XmlSchema Annotated.
        JAXBContext jc = JAXBContext.newInstance("org.example.xml");
        // If you didn't...
        // Give the ObjectFactory class directly.
        // // JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class)
        Unmarshaller unmarshaller = jc.createUnmarshaller();

        // Unmarshal Example
        File xml= new File("src/org/example/xml/example.xml");
        JAXBElement<AltNum1Type> je = 
            (JAXBElement<AltNum1Type>) 
                unmarshaller.unmarshal(xml);
        // ObjectFactory is involved in the above process.
        // When you're done, you can now import the Value.
        // It doesn't matter if multiple elements of the same type become root.
        AltNum1Type root = je.getValue();
    }

Attention, as we saw in the example above, casting should be done directly, but if you cast incorrectly, casting errors will occur.

See the https://dzone.com/articles/jaxb-and-root-elements documentation. If you look, you can also mix it with the regular @XmlRootElement.

However, I recommend using xjc if possible.


2022-09-22 21:58

You can use @XmlType instead of @XMLRootElement and wrap it around JAXBElement to dynamically change the root element.

JAXBElement If you have a Company class, you can use it this way.

JAXBElement a = new JAXBElement(new QName("new-name"), Company.class, company);


2022-09-22 21:58

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.