views:

1199

answers:

3

For example, I've got a simple schema which imports another schema. The second schema (urn:just:attributes, just-attributes.xsd) just defines an attribute group.

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/MySchema"
    xmlns:tns="http://www.example.org/MySchema" 
    elementFormDefault="qualified"
    xmlns:ja="urn:just:attributes">

    <import schemaLocation="just-attributes.xsd" namespace="urn:just:attributes"/>

    <element name="MyElement">
        <complexType>
            <attributeGroup ref="ja:AttributeGroup"/>
        </complexType>
    </element>
</schema>

I'm using the Metro xjc Ant task to generate classes off of this schema. The problem I'm running into is that the third party application I'm interacting with is peculiar about namespaces. This case I need a String value, so I have to serialize it. I use boilerplate code for this.

private static <T> String marshal(T object) throws JAXBException{
    OutputStream outputStream = new ByteArrayOutputStream();
    JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.marshal(object, outputStream);
    return outputStream.toString();
}

Which gives me something along the lines of

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:MyElement xmlns:ns1="urn:just:attributes" xmlns:ns2="http://www.example.org/MySchema" ns1:attrib1="1234" ns1:attrib2="5678"/>

The problem I have is that this third party expects something like xmlns:thirdpartyns="urn:just:attributes", which is to say, they are parsing based on the name given to the namespace. It has to be "thirdpartyns" for their software to work.

Does anyone know of a way around this, short of doing a find and replace in the resulting string? A custom binding rule perhaps?

+1  A: 

http://www.func.nl/community/knowledgebase/customize-namespace-prefix-when-marshalling-jaxb

This shows how to do it.

DaveC
Thanks. This works like a charm!
Tom
A: 

There is a way of doing this, which uses an internal JAXB implementation class called NamespacePrefixMapper. In the JAXB RI, this is in com.sun.xml.bind.marshaller, but in Java6, it's in com.sun.xml.internal.bind.marshaller.

This is an abstract class, which you can subclass and implement the abstract method which maps namespace URIs on to prefixes.

You then inject an instance of that subclass into the marshaller:

JAXBContext context = ...
Marshaller marshaller = context.createMarshaller();
NamespacePrefixMapper prefixMapper = new MyPrefixMapperImpl();
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", prefixMapper);

The property name is going to be different for the Java6 version, but you get the idea.

Note that this is an internal JAXB implementation class, so there's no guarantee it'll be there in future versions.

skaffman
A: 

Hi all

maybe this is a silly question;

is it possible set the namespace as "" in order to have something like

<MyElement 
  xmlns="urn:just:attributes" 
  xmlns="http://www.example.org/MySchema" 
  attrib1="1234" 
  attrib2="5678"/> 

instead of

<ns2:MyElement 
  xmlns:ns1="urn:just:attributes" 
  xmlns:ns2="http://www.example.org/MySchema" 
  ns1:attrib1="1234" ns1:attrib2="5678"/> 

have a single XSD file is the only way?

gilberto