Search code examples
javaxstream

Namespace qualified attributes with XStream


I am using XStream to generate XML from several Java classes and I need to specify namespace qualified attributes for some elements; namely xml:id and xlink:href attributes.

I am using the StaxDriver and I can configure namespaces for elements using a QNameMap, it is just namespaces for attributes that I haven't found a solution for.

Essentially, I have a class

@XStreamAlias("someElement")
public class SomeElement
{        
    @XStreamAsAttribute
    String id = "foo";
    @XStreamAsAttribute
    String href = "http://bar"
}

and I need this to serialize to:

<someElement xml:id="foo" xlink:href="http://bar"/>

To complicate matters I can not assume that any attribute named 'id' should become an "xml:id", or that any attribute named 'href' should become an 'xlink:href'.


Solution

  • After a bit more Googling I think I have found the answer, and the solution is simpler than I thought.

    I was being too clever and looking for some way to make some component "namespace aware", and that was a losing battle. The solution I found was to forget about the StaxDriver and QNameMaps and simply massage fields with @XStreamAsAttribute and @XStreamAlias to generate the required namespace atributes. I.E.

    @XStreamAlias("root")
    class RootElement
    {
        @XStreamAsAttribute
        final String xmlns = "http://www.example.org"
    
        @XStreamAsAttribute 
        @XStreamAlias("xmlns:xlink")
        final String xlink="http://www.w3.org/1999/xlink"
    
        SomeElement someElement
    }
    
    class SomeElement
    {
        @XStreamAsAttribute 
        @XStreamAlias("xml:id")
        String id
    
        @XStreamAsAttribute 
        @XStreamAlias("xlink:href")
        String href
    }
    

    With the above I get the desired XML:

    <root xmlns="http://www.example.org" xmlns:xlink="http://www.w3.org/1999/xlink">
        <someElement xml:id="p1" xlink:href="http://www.example.org"/>
    </root>
    

    That is likely not the best, or proper, way to go about it, but it does what I need for now.