troyal
troyal

Reputation: 2519

How do I assign a boolean value based on the existence of an element in JAXB?

This is somewhat related to this question and this question which I asked yesterday.

I would like to use a boolean to determine whether or not an element exists in an XML document. The files that I am parsing allow for elements such as the following:

<FamilyMember>
    <Name>Jeff</Name>
</FamilyMember>
<FamilyMember>
    <Name>Spot</Name>
    <IsPet/>
</FamilyMember>

In this example, the element specifies that the FamilyMember is a pet, but there is no additional data associated with this element. I would like to be able tell JAXB to return a boolean based on whether or not the element exists in the parsed file. If the element exists, the value should be true; otherwise, it should be false. I would like to to this from within the XSD schema which I use to generate my Java classes, if possible.

Upvotes: 4

Views: 2878

Answers (2)

bdoughan
bdoughan

Reputation: 149047

You should be able to do this with an XmlAdapter similar to the following:

Once you have the answer to ( How do I specify the adapter(s) which JAXB uses for marshaling/unmarshaling data?) you will be able to apply the adapter.


The following is how it could be done. Note the following example works using EclipseLink JAXB (MOXy), but throws an exception when the JAXB reference implementation is used.

FamilyMember

package example;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name="FamilyMember")
public class FamilyMember {

    private boolean pet;
    private String name;

    @XmlElementRef
    @XmlJavaTypeAdapter(IsPetAdapter.class)
    public boolean isPet() {
        return pet;
    }

    public void setPet(boolean pet) {
        this.pet = pet;
    }

    @XmlElement(name="Name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

IsPetAdapter

package example;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import forum204.IsPetAdapter.IsPet;

public class IsPetAdapter extends XmlAdapter<IsPet, Boolean> {

    @Override
    public Boolean unmarshal(IsPet v) throws Exception {
        return null != v;
    }

    @Override
    public IsPet marshal(Boolean v) throws Exception {
        if(v) {
            return new IsPet();
        }
        return null;
    }

    @XmlRootElement(name="IsPet")
    public static class IsPet {
    }

}

Demo

package example;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(FamilyMember.class);

        Unmarshaller unmarshaller= jc.createUnmarshaller();
        FamilyMember fm = (FamilyMember) unmarshaller.unmarshal(new File("input.xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(fm, System.out);
    }

}

Upvotes: 3

djna
djna

Reputation: 55957

Does your IsPet manifest as a Boolean? In which I case I'd guess that the Boolean would be null if it's not present in the XML. I think this questionindicates this is the case.

Upvotes: 0

Related Questions