Reputation: 39477
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>
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).
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?
@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;
.............
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
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