Nishant
Nishant

Reputation: 71

JAXB adding namespace to parent but not to the child elements contained

I put together an XSD and used JAXB to generate classes out of it.

Here are my XSDs-

myDoc.xsd :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.mydoc.org"
       targetNamespace="http://www.mydoc.org"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:mtp="http://www.mytypes.com" elementFormDefault="qualified">

<xs:import namespace="http://www.mytypes.com" schemaLocation="mytypes.xsd" />
<xs:element name="myDoc">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="crap" type="xs:string"/>
      <xs:element ref="mtp:foo"/>
      <xs:element ref="mtp:bar"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

mytypes.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.mytypes.com"
       xmlns="http://www.mytypes.com"
       xmlns:tns="http://www.mytypes.com"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       attributeFormDefault="qualified" elementFormDefault="qualified">


  <xs:element name="foo" type="tns:Foo"/>
  <xs:element name="bar" type="tns:Bar"/>
  <xs:element name="spam" type="tns:Spam"/>

  <xs:simpleType name="Foo">
    <xs:restriction base="xs:string"></xs:restriction>
  </xs:simpleType>

  <xs:complexType name="Bar">
    <xs:sequence>
      <xs:element ref="spam"/>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="Spam">
    <xs:restriction base="xs:string" />
  </xs:simpleType>

</xs:schema>

The document marshalled is-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myDoc xmlns:ns2="http://www.mytypes.com">
  <crap>real crap</crap>
  <ns2:foo>bleh</ns2:foo>
  <ns2:bar>
    <spam>blah</spam>
  </ns2:bar>
</myDoc>

Note that the <spam> element uses the default namespace. I would like it to use the ns2 namespace. The schema (mytypes.xsd) expresses the fact that <spam> is contained within <bar> which in the XML instance is bound to the ns2 namespace.

I've broken my head over this for over a week and I would like ns2 prefix to appear in <spam>. What should I do?

Required :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myDoc xmlns:ns2="http://www.mytypes.com">
  <crap>real crap</crap>
  <ns2:foo>bleh</ns2:foo>
  <ns2:bar>
    <ns2:spam>blah</ns2:spam><!--NS NS NS-->
  </ns2:bar>
</myDoc>

Upvotes: 7

Views: 12042

Answers (6)

VirajC
VirajC

Reputation: 68

You can specify it in your package-info.java in @XmlSchema annotation.

elementFormDefault=XmlNsForm.QUALIFIED

sample package-info.java

@XmlSchema(
    namespace="desiredNamespace",   
    // If qualified namespace will be added to all elements
    elementFormDefault = XmlNsForm.QUALIFIED,
    // If qualifies namespace will be added to all attributes
    attributeFormDefault = XmlNsForm.UNQUALIFIED,
    xmlns = {   
        @XmlNs(prefix = "xsd", namespaceURI = "desiredNamespace"),
        @XmlNs(prefix = "xsi", namespaceURI = "anotherLink"),
    }
)

Upvotes: 0

Tushar
Tushar

Reputation: 21

check if the fields in a generated classed are missing the @XmlElement annotation and if present are they missing the namespace attribute. These two are must in order to get the namespace prefix against every element in your marshaled xml

Upvotes: 2

aravind
aravind

Reputation: 1

Did u check your code that you have specified your ElementType as "Spam" but referred under bar as "spam". this capital "S" and small "s" in ur code, if doesnt bother, i am sorry but if it really bothers, u may have to use it properly. Try use "Spam" across everywhere and check it out na..

-- sorry, i am a beginner in xslt, xml, xsd and stuffs and no knowledge about JAXB. but in general, when we read about writing xml documents using Xsd's, we would always take care of case sensitiveness as well.

sorry if this answer doesnt solve ur problem.

Upvotes: -1

Glenn Bech
Glenn Bech

Reputation: 6182

This Error also occurs if you build with Maven 2 and the following jaxws-maven-plugin.

 <groupId>org.codehaus.mojo</groupId>
 <artifactId>jaxws-maven-plugin</artifactId>

And for some reason have configured the maven-compiler-plugin for java 1.5. Setting target/source to 1.6 fixes the problem.

 <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        </configuration>
 </plugin>

If you know why, please feel free to comment.

Upvotes: 0

Nishant
Nishant

Reputation: 71

package-info.java was not being compiled by my build system and hence elementFormDefault="qualified" and the target namespace did not make it to the Jaxb annotated classes.

If you see this behavior, make sure your package-info.java is being compiled into a .class file and is in your classpath.

Cheers.

Upvotes: 0

Julien Rentrop
Julien Rentrop

Reputation: 651

I have tried to reproduce your problem, but here it's working correctly: When marshalling the spam element does get a ns2 namespace.

My marshalling code:

    Bar bar = new Bar();
    bar.setSpam("s");

    MyDoc myDoc = new MyDoc();
    myDoc.setBar(bar);

    JAXBContext context = JAXBContext.newInstance("org.mydoc");

    Marshaller marshaller = context.createMarshaller();
    marshaller.marshal(myDoc, System.out);

Output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><myDoc xmlns="http://www.mydoc.org" xmlns:ns2="http://www.mytypes.com"><ns2:bar><ns2:spam>s</ns2:spam></ns2:bar></myDoc>

My JAXB version:

xjc version "JAXB 2.1.3 in JDK 1.6"
JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build IBM JAXB 2.1.3 in JDK 1.6)

EDIT:

The Bar.java class does have the following annotation:

@XmlElement(required = true)
protected String spam;

The XmlElement also has a namespace attribute. Javadoc: http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElement.html#namespace()

By default it will look at the @XmlSchema annotation in the com.mytypes package. Did you remove the @XmlSchema annotation and/or the package-info.java file?

Upvotes: 0

Related Questions