# [JAXB] @XmlAnyElement namespace



## Mewel (12. Jul 2011)

Hallo,

folgende Situation: ich füge ein w3c.DOM-Element (mit Namespace ohne Prefix) in ein mit @XmlAnyElement annotiertes Objekt ein und machen dann ein Marshalling. Leider wird dabei automatisch ein Prefix angehängt + ein zusätzlicher Namespace generiert. Ich habe mal ein einfaches Beispielprogramm geschrieben was den Effekt zeigt.


```
public class JAXBNamespaceTest {

    private static JAXBContext jaxbContext;

    private static Marshaller marshaller;

    static {
        try {
            jaxbContext = JAXBContext.newInstance(TestJAXB.class);
            marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
    
    public void nsTest() throws Exception {
        // create dom
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        org.w3c.dom.Document doc = builder.newDocument();
        org.w3c.dom.Element e = doc.createElement("dom");
        e.setAttribute("xmlns", "www.google.de");
        doc.appendChild(e);
        // print dom
        System.out.println("So möchte ich das haben, ein Element ohne Prefix mit Namespace Attribut");
        xmlOut(doc); // perfect - only one xmlns tag
        System.out.println();
        System.out.println();

        // create jaxb stuff
        TestJAXB testJAXB = new TestJAXB();
        testJAXB.desciption.any = e;
        System.out.println("Und hier mit Prefix 'dom' und extra Namespace 'xmlns:dom'");
        marshaller.marshal(testJAXB, System.out); // why dom:dom and xmlns:dom? 
    }

    @XmlRootElement(name="test")
    public static class TestJAXB {
        public DescriptionType desciption = new DescriptionType();
    }

    @XmlType(name = "descriptionType")
    public static class DescriptionType {
        @XmlAnyElement(lax = false)
        public Object any;
    }

    public static void xmlOut(org.w3c.dom.Document doc) throws Exception {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        Source source = new DOMSource(doc);
        Result output = new StreamResult(System.out);
        transformer.transform(source, output);
    }

    public static void main(String[] args) throws Exception {
        JAXBNamespaceTest nsTest = new JAXBNamespaceTest();
        nsTest.nsTest();
    }
}
```

Also mein Ziel ist:
[XML]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test>
    <desciption>
        <dom xmlns="www.google.de"/>
    </desciption>
</test>
[/XML]

Hat jemand eine Idee wie ich das erreichen kann?


----------



## eRaaaa (12. Jul 2011)

Mhm, also viel habe ich mit JAXB bisher nicht gemacht und daher jetzt nur Halbwissen:



> Hat jemand eine Idee wie ich das erreichen kann?



Probiere es mal bei dem DescriptionType so:


```
@XmlType(name = "descriptionType")
    public static class DescriptionType {
        @XmlElement
        public Object dom;
    }
```

die eine Zeile muss dann natürlich entsprechend geändert werden

```
testJAXB.desciption.dom = e;
```

allerdings sieht das irgendwie alles merkwürdig aus (zumindest für mich als Halbwissender )


----------



## Mewel (12. Jul 2011)

Vielen Dank, das funktioniert .

Einziges Problem ist jetzt noch das die JAXB-Klassen mit XJC automatisch generiert werden. Muss ich mir das XJB-Binding nochmal anschauen ob ich da ansetzten kann.


----------



## Mewel (12. Jul 2011)

Geht leider doch nicht, das Problem mit @XmlElement ist, das der Name nicht vom DOM-Element kommt (doc.createElement("hier_muss_was_variables_stehen")), sondern durch die Klasse vorgegeben ist.


----------



## Mewel (22. Jul 2011)

Habe eine Lösung gefunden:


```
public class NamespaceFilter extends XMLFilterImpl {

    private String xmlns = "";

    @Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        if(uri.equals(xmlns)) {
            super.startElement(uri, localName, localName, atts);
        } else {
            super.startElement(uri, localName, qName, atts);
        }
    }

    @Override
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        if(prefix == null || prefix.length() == 0) {
            xmlns = uri;
        }
    }

}
```

Und marshalling mit:

```
NamespaceFilter outFilter = new NamespaceFilter();
SAXHandler saxHandler = new SAXHandler();
outFilter.setContentHandler(saxHandler);
marshaller.marshal( your_jaxb_element, outFilter);
return saxHandler.getDocument()
```


----------

