peter.petrov
peter.petrov

Reputation: 39477

JAXB - marshall (uppercase, lowercase, namespaces, ns2)

I have about 100 (if not more) Java classes generated from a big XSD file via xjc.

That XSD file has upper-case names for its elements. Now, when I marshall one object from these generated Java classes, I have a few issues.

Sample XML produced by JAXB marshall:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<advertiser xmlns:ns2="http://p.t.com/service">
    <ns2:Name>TEST Adv 001</ns2:Name>
</advertiser>
  1. The names of the elements (but not those of the sub-elements) are produced by JAXB in lower-case. I need them to be upper-case (as they are in the XSD).

  2. There are some strange ns2: prefixes to the names of the elements e.g. I want the xmlns:ns2 in this example to become just xmlns, and the ns2:Name to become just Name. One answer here on SO suggested putting attributeFormDefault="unqualified" in the XSD, but seems that didn't help me either.

How can I solve these two issues?

I looked here for similar question but don't find one quite identical to mine. Also the answers there look pretty complicated and they ask to change the Java classes which I cannot do. Why should this be so complicated?!

Note that my Java classes are auto-generated, so I don't want to change them manually.

I wonder why the XSD says one thing, and the JAXB marshall process produces another thing. Shouldn't the JAXB marshall generate XML which is 100% compliant with the XSD?

Edit

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Advertiser", propOrder = {

})
public class Advertiser {

    @XmlElement(name = "TelID")
    protected Integer telID;

    @XmlElement(name = "Name")
    protected String name;

    @XmlElementRef(name = "Address", namespace = "http://p.t.com/service", type = JAXBElement.class)
    protected JAXBElement<String> address;

.............

Edit 2

    Advertiser adv = new Advertiser();
    adv.setName("TEST Adv 001");

    StringWriter sw = new StringWriter();
    JAXB.marshal(adv, sw);
    System.out.println(sw.toString());

Upvotes: 4

Views: 2739

Answers (1)

lexicore
lexicore

Reputation: 43689

1) Strange. Since you've generated classes from XSD they should have adequate annotations and if elements in XSD were uppercase, you should get @XmlElement annotations with uppercase element names. Post a couple of schema-derived classes, interesting what they look like. You are right that when you generate classes from an XSD, you should get XML (more or less) conforming to the XSD when marshalling. At least the case of elements should match. This is very strange, I can't explain it. Post your classes, we'll see.

2) See

Is it possible to customize the namespace prefix that JAXB uses when marshalling to a String?

Update.

Ok, now I see where the problem is. You marshal an instance of Advertiser, but it is just an @XmlType not a @XmlRootElement. So JAXB does not know in which root element it should be marshalled and does something by default which produces advertiser, lowcase, in empty namespace.

To solve this you could either add @XmlRootElement annotation or wrap your Advertiser instance into a JAXBElement.

For the latter check for the ObjectFactory class in the same package as the Advertiser class. You could the do (something like):

ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<Advertiser> advElement = objectFactory.createAdvertiser(adv);

Marshalling advElement should give you the correct element name.

When compiling XML Schemas, XJC generates such createXYZ(XYZ value) methods for each of the global elements.

Upvotes: 0

Related Questions