Kenneth De Leon
Kenneth De Leon

Reputation: 33

JAXB Nested XML - List<Object> same names with attributes: unable to display XML data

I have an xml that looks like this

<?xml version="1.0" encoding="UTF-8"?>
<TestCases>
  <TestCase id="TC04">
    <statement sequence="1">This is TC04, statement 1</statement>
    <statement sequence="2">This is TC04, statement 2</statement>
    <statement sequence="3">This is TC04, statement 3</statement>
    <statement sequence="4">This is TC04, statement 4</statement>
  </TestCase>
  <TestCase id="TC05">
    <statement sequence="1">This is TC05, statement 1</statement>
    <statement sequence="2">This is TC05, statement 2</statement>
    <statement sequence="3">This is TC05, statement 3</statement>
    <statement sequence="4">This is TC05, statement 4</statement>
  </TestCase>
</TestCases>

So far, I am able to get all TestCase under TestCases and display the sequence numbers.

TC04 1=null, 2=null, 3=null, 4=null TC05 1=null, 2=null, 3=null, 4=null

However, when displaying the values, I am getting null. I think this needs an XMLAdapter but I am not familiar nor able to comprehend how to create an Adapter that reads/stores the attribute and xml data of statement node.

Below is my Java code.

package Test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

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

    @XmlElement(name = "TestCase")
    private List<TestCase> testcases;

    public List<TestCase> getTestCases() {
        if (this.testcases == null)
            this.testcases = new ArrayList<TestCase>();
        return testcases;
    }

    @XmlRootElement(name = "TestCase")
    public static class TestCase {

        @XmlAttribute(name = "id")
        private String id;

        public String getId() {
            return this.id;
        }

        @XmlElement(name = "statement")
        public List<Statement> statements;

        public List<Statement> getStatements() {
            if (this.statements == null)
                this.statements = new ArrayList<Statement>();
            return statements;
        }

        @XmlRootElement(name = "statement")
        public static class Statement {
            private String name;

            @XmlAttribute(name = "sequence")
            private String sequence;

            public String getSequence() {
                return this.sequence;
            }

            public String getStatement() {
                return this.name;
            }
        }

    }
}

Upvotes: 0

Views: 277

Answers (1)

Nesku
Nesku

Reputation: 501

  1. You should use @XmlRootElement only on TestCases.
  2. You also might need to use @XmlValue on name and then add @XmlAccessorType(XmlAccessType.FIELD) on your class. This post could probably help.

    @XmlRootElement(name = "TestCases")
    public class TestCases {
    
        @XmlElement(name = "TestCase")
        private List<TestCase> testcases;
    
        public List<TestCase> getTestCases() {
            if (this.testcases == null)
                this.testcases = new ArrayList<TestCase>();
            return testcases;
        }
    
        public static class TestCase {
    
            @XmlAttribute(name = "id")
            private String id;
    
            public String getId() {
                return this.id;
            }
    
            @XmlElement(name = "statement")
            public List<Statement> statements;
    
            public List<Statement> getStatements() {
                if (this.statements == null)
                    this.statements = new ArrayList<Statement>();
                return statements;
            }
    
            @XmlAccessorType(XmlAccessType.FIELD)
            public static class Statement {
                @XmlValue
                private String name;
    
                @XmlAttribute(name = "sequence")
                private String sequence;
    
                public String getSequence() {
                    return this.sequence;
                }
    
                public String getStatement() {
                    return this.name;
                }
            }
    
        }
    }
    

Upvotes: 1

Related Questions