Hi,

This is part of my schema (the whole thing is quite complex and inline in a WSDL document): <xsd:schema targetNamespace="http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget"; xmlns:tns="http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget";
                   attributeFormDefault="qualified"
                   elementFormDefault="qualified">
<xsd:element name="ScheduledEmailQueryRequest" type="tns:ScheduledEmailQueryRequestType"></xsd:element> <xsd:element name="ScheduledEmailQueryResponse" type="tns:ScheduledEmailQueryResponseType"></xsd:element>
...
           <xsd:complexType name="ScheduledEmailQueryResponseType">
               <xsd:sequence>
<xsd:element name="Message" type="tns:EmailMessageDefinition" maxOccurs="unbounded" minOccurs="0"></xsd:element>
               </xsd:sequence>
           </xsd:complexType>
           <xsd:complexType name="EmailMessageDefinition">
               <xsd:sequence>
<xsd:element name="To" minOccurs="0" type="tns:EmailRecipient" maxOccurs="unbounded"></xsd:element> <xsd:element name="From" type="tns:EmailAddress"></xsd:element> <xsd:element name="Subject" type="xsd:normalizedString"></xsd:element>
...
               </xsd:sequence>
               <xsd:attribute name="ID" type="xsd:string" use="required"/>
           </xsd:complexType>

The noticeable thing is that the EmailMessageDefinition element has an attribute called ID and that it should be namespace qualified (attributeFormDefault="qualified" ).

Using CXF as a SOAP processor works correctly for everything I've tried with it so far, my problem comes when I try to marshall an EmailMessageDefinition manually:

EmailMessageDefinition defn = createMessageDefinition( "id", "payload" ); // returns an EmailMessageDefinition with the id set to "id" and some standard recipients

       try
       {
           JAXBDataBinding binding = new JAXBDataBinding();
JAXBContext jc = JAXBContext.newInstance( "com.groupgti.esb.jobengines.email.service.groupgtisupportsystem.emailschedulertarget" );
           Marshaller marshaller = jc.createMarshaller();
           StringWriter writer = new StringWriter();

marshaller.marshal( new JAXBElement( new QName( "http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget";, "EmailMessageDefinition" ), EmailMessageDefinition.class, defn ), writer );
           System.out.println( writer.toString() );

That gives:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns1:EmailMessageDefinition ns1:ID="id" xmlns:ns1="http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget";>...</ns1:EmailMessageDefinition> Which is correct, but the namespace is repeated all over the place and is ugly.

So I try to make it the default namespace by adding:
   private class NamespaceMapper extends NamespacePrefixMapper
   {

       @Override
public String getPreferredPrefix( String namespaceUri, String suggestion, boolean requirePrefix )
       {
if( "http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget".equals( namespaceUri ) )
           {
               return "";
           }
           else
           {
               return suggestion;
           }
       }

   }

And this is the result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><EmailMessageDefinition ID="id" xmlns="http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget";>...</EmailMessageDefinition> That result is wrong, according to the schema, because the attribute is not affected by the default namespace. This can be demonstrated by unmarshalling the result, which fails to set the ID on the resulting object.

I tried adding:
       @Override
       public String[] getPreDeclaredNamespaceUris2()
       {
String[] result = { "ns", "http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget"; };
           return result;
       }
but that didn't help:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns:EmailMessageDefinition ID="id" xmlns="http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget"; xmlns:ns="http://groupgti.com/esb/jobengines/email/service/GroupGtiSupportSystem/EmailSchedulerTarget";>...</ns:EmailMessageDefinition>

I think the marshaller needs special handling for qualified attributes with an enforced default namespace.

1. Please can you confirm that this is a bug and not my incompetence (if you'd like me to file it please point me in the right direction). 2. Do you know a workaround that will put the elements in the default namespace? If not, the workaround is to namespace everything, which is done correctly.

Thanks

Jim


Reply via email to