JAXB Fragment Marshal w/o namespace

27,494

Solution 1

Assuming you want the default namespace for your document to be http://www.namespace.com, you could do the following:

Demo

The XMLStreamWriter.setDefaultNamespace(String) and XMLStreamWriter.writeNamespace(String, String) methods will be used to set and write the default namespace for the XML document.

package forum9297872;

import javax.xml.bind.*;
import javax.xml.stream.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(System.out);
        writer.setDefaultNamespace("http://www.namespace.com");

        JAXBContext jc = JAXBContext.newInstance(WorkSet.class);
        Marshaller m = jc.createMarshaller();
        m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

        writer.writeStartDocument();
        writer.writeStartElement("http://www.namespace.com", "Import");
        writer.writeNamespace("", "http://www.namespace.com");
        writer.writeStartElement("WorkSets");

        m.marshal(new WorkSet(), writer);
        m.marshal(new WorkSet(), writer);

        writer.writeEndDocument();
        writer.close();
    }

}

WorkSet

My assumption is that you have specified namespace information in your JAXB model.

package forum9297872;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="WorkSet", namespace="http://www.namespace.com")
public class WorkSet {

}

Output

Below is the output from running the demo code:

<?xml version="1.0" ?><Import xmlns="http://www.namespace.com"><WorkSets><WorkSet></WorkSet><WorkSet></WorkSet></WorkSets></Import>

Solution 2

There are three workarounds for this.

1) Create JAXB annotated objects for the container of your workersets. Add the workersets to that object and then marshal the whole thing.

2) Follow the first example in 101 ways to marshal objects with JAXB and use DocumentBuilderFactory with namespace aware.

3) Assuming that the jaxb object is in a package that should never have qualified namespaces you can add the following to the package annotation: (note: it's been a while since i've done this and I havn't tested this code)

@XmlSchema(namespace = "", elementFormDefault = XmlNsForm.UNQUALIFIED) 
package example;
Share:
27,494
TyC
Author by

TyC

Unloyal glory hunter

Updated on August 04, 2022

Comments

  • TyC
    TyC almost 2 years

    I'm using the JAXB_FRAGMENT property for my marshaller to marshal at the WorkSet level. The problem is that when I marshal it's giving the WorkSet element the xmlns attribute everytime. Is there a way to marshal so that it doesn't attach the xmlns attribute? Here's what my XML looks like.

        <Import>
            <WorkSets>
                <WorkSet xmlns="http://www.namespace.com">
                    <Work>
                    <Work>
                    ...
                    ..
                    ...
                </WorkSet>
                <WorkSet xmlns="http://www.namespace.com">
                    <Work>
                    <Work>
                    ...
                </WorkSet>
            </WorkSets>
        </Import>
    

    Here's the code I'm using the create the above:

    FileOutputStream fos = new FileOutputStream("import.xml");
    XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(fos);
    
    JAXBContext jc = JAXBContext.newInstance(WorkSet.class);
    Marshaller m = jc.createMarshaler();
    m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    
    writer.writeStartDocument();
    writer.writeStartElement("Import");
    writer.writeAttribute("xmlns","http://www.namespace.com");
    writer.writeStartElement("WorkSets");
    
    while(hasWorkSet){
    m.marshal(workSet, writer)
    }
    writer.writeEndDocument();
    writer.close();
    
  • TyC
    TyC about 12 years
    This worked, yet I have no idea why. There was no name specified in the WorkSet class. Here's the XmlRootElement tag attached to the class. @XmlRootElement(name = "WorkSet").
  • bdoughan
    bdoughan about 12 years
    Is there a package-info class in the same package as the WorkSet class?
  • TyC
    TyC about 12 years
    Yes. It contains the following: @javax.xml.bind.annotation.XmlSchema(namespace = "itron.com/nVanta", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
  • TyC
    TyC about 12 years
    Also, is there a way to get formatted output? I'm already using the formatted output property on the marshaller, but I don't think it's working because I'm using the fragmeted property as well. Or perhaps because I'm using a FileOutputStream.
  • bdoughan
    bdoughan about 12 years
    The package-info class is where the namespace is coming from: blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes.html. You just need to set marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); to get formatted output: blog.bdoughan.com/2011/08/…
  • TyC
    TyC about 12 years
    I have the Marshaller.JAXB_FORMATTED_OUTPUT property set. The WorkSet element is still not coming out formatted.
  • bdoughan
    bdoughan about 12 years
    Sorry, it is because your FileOutputStream is wrapped in an XmlStreamWriter that is why your output is not being formatted.
  • dma_k
    dma_k about 12 years
  • Stephane
    Stephane about 8 years
    Add a public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException { if (!"nil".equals(localName)) { to also strip the nil attribute.
  • truekiller
    truekiller almost 3 years
    Could you please help me on stackoverflow.com/questions/68031311/…
  • truekiller
    truekiller almost 3 years
    Could you please help me on stackoverflow.com/questions/68031311/…
  • Stephane
    Stephane almost 3 years
    Sorry I have not touched that framework in a long time now and could not help you with my limited understanding as of today.