Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html

This shows how to do it.

Another: http://www.systemmobile.com/?p=280

Key bits in case that link dies too:

the NamespacePrefixMapper class, found in the com.sun.xml.bind.marshaller package. The abstract class has one method to implement:

public abstract String getPreferredPrefix(  
     String namespaceUri,         
     String suggestion,         
     boolean requirePrefix); 

then

Marshaller marshaller =        
    jaxbContext.createMarshaller();        
marshaller.setProperty(”com.sun.xml.bind.namespacePrefixMapper”,        
    new MyNamespacePrefixMapper());  

If you’re also using javax.xml.xpath.XPath, your NamespacePrefixMapper can also implement javax.xml.namespace.NamespaceContext, centralizing your namespace customization in a single class.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...