1

I have an XML to unmarshall with JAXB. The code works fine if I remove all namespace attributes from the elements but I get a null object after unmarshalling if I keep the namespace attributes.

The XML is like this:

<Animal  xmlns="http://allmycats.com/serviceplatform/1.0/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Cat z:Id="i3" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<name>kitty</name>
</Cat>
<Cat z:Id="i2" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<name>kitty2</name>
</Cat>
</Animal>

My Animal bean is like this:

    @XmlRootElement(name = "Animal")
public class Animal{
    List<Cat> cats;

    @XmlElement(name = "Cat")
    public List<Cat> getCats() {
        return cats;
    }

    public void setCats(List<Cat>cats) {
        this.cats= cats;
    }
}

The Cats bean is like:

@XmlRootElement(name = "Cat")
public class Cat {
    private String zId;

    @XmlAttribute(name = "z:Id", namespace="http://schemas.microsoft.com/2003/10/Serialization/")
    public String getzId() {
        return zId;
    }
    public void setzId(String zId) {
        this.zId = zId;
    }

    private String name;
    @XmlElement(name = "name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

At runtime, I get an empty object. I tried to remove "z:" from the attribute and I got this exception:

org.xml.sax.SAXParseException; The prefix "z" for attribute "z:Id" associated with an element type "Cat" is not bound.]

If I remove namespaces from cat and Animal, I get this exception:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://allmycats.com/serviceplatform/1.0/", local:"Animal"). Expected elements are <{}Animal>

Final code to unmarshall is below. The last line gives a null pointer exception

File file = new File(filepath1);
System.out.println("file exists? : "+ file.exists()); // prints true

JAXBContext jaxbContext = JAXBContext.newInstance(Animal2.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Animal2 animals = (Animal2)jaxbUnmarshaller.unmarshal( file );
System.out.println("--file size: "+animals.getCats().size());

I am not sure how to handle the namespaces and the z: attributes in my POJO classes. Any suggestions please ?

The code works fine if I do not have any namespace or any attribute with namespace in the XML but I cannot alter the XML.

Gaurav Jeswani
  • 4,410
  • 6
  • 26
  • 47
Riju Mahna
  • 6,718
  • 12
  • 52
  • 91

1 Answers1

2

XMLAtribute has atribute namesape, so

@XmlAttribute(name = "Id", namespace="http://schemas.microsoft.com/2003/10/Serialization").

While judging by your xml, the cat is in the same namespace as the animal so

The following code works with JDK 7 (fixed the ns for animal and attribute name for zid).

@XmlRootElement(name = "Animal",namespace = "http://allmycats.com/serviceplatform/1.0/")
public class Animal2{
    List<Cat2> cats;

    @XmlElement(name = "Cat")
    public List<Cat2> getCats() {
        return cats;
    }

    public void setCats(List<Cat2>cats) {
        this.cats= cats;
    }
}
@XmlRootElement(name = "Cat")
public class Cat2 {
    private String zId;

    @XmlAttribute(name = "Id", namespace="http://schemas.microsoft.com/2003/10/Serialization/")
    public String getzId() {
        return zId;
    }
    public void setzId(String zId) {
        this.zId = zId;
    }

    private String name;

    @XmlElement(name = "name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
Zielu
  • 8,312
  • 4
  • 28
  • 41
  • I've changed the values but the namespace structure is the same. I added NS to `Id` element and changed the NS on `Cat` but the output is still blank object. Could this be due to the `xmlns:i` attribute in `Animal` ? – Riju Mahna Feb 19 '15 at 22:27
  • Your xml is broken so it is a bit of guessing ( instead of ) and it should not be i but xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Take your original xml document and generated the xsd schema for it http://www.freeformatter.com/xsd-generator.html#ad-output (and fix it till it is valid xml). Then generate your classes from the schema (http://stackoverflow.com/questions/11463231/how-to-generate-jaxb-classes-from-xsd) (your IDE can also do it for you). You can tweek them or use as template to understand namespace issues. Dealing with namespaces is always a pain. – Zielu Feb 19 '15 at 23:08
  • Sorry about the xml. I've fixed it. The actual xml is system generated and is over 150 MB in size. So this replica is all I have for now.... The namespaces and attributes are all actual. – Riju Mahna Feb 20 '15 at 00:09
  • Remove namespaces from Cat and Animal, add @XmlAttribute(name = "Id", namespace = "http://schemas.microsoft.com/2003/10/Serialization/") to Id and it works. I tested it on your xml file (after fixing the , in cat and extra >) – Zielu Feb 20 '15 at 01:06
  • I've updated the XML and classes to exactly what I am using now, After removing the namespaces from Animal and Cat, I get the new exception :` javax.xml.bind.UnmarshalException: unexpected element (uri:"http://allmycats.com/serviceplatform/1.0/", local:"Animal"). Expected elements are <{}Animal>` – Riju Mahna Feb 20 '15 at 02:11
  • I am still getting a blank object after unmarshall... I've updated my unmarshalling code in the questn.... And I am also using JDK7 ...Really appreciate your time and efforts on this question, means a lot. – Riju Mahna Feb 20 '15 at 03:29
  • Not it is a dbugging problem not jaxb one (your code mixes mine classes and yours). a) dbl check your input xml. b) fill up objects and marshl them to xml, compare outputs c) unmarshal previously marshalled see if it worked. Start with clean project, classes, maybe your IDE cached somehtign. – Zielu Feb 20 '15 at 13:42
  • Good answer :) More or Less is the same that i wrote [here](http://stackoverflow.com/a/28678845/3364187) :) – Xstian Feb 24 '15 at 09:16