I have a list called Documents that is comprised of different Document objects I created. I am trying to serialize the list to look like this:
<Documents>
<Document>
.
.
.
</Document>
<Document>
.
.
.
</Document>
</Documents>
This is is what I have in code:
@XmlElementWrapper(name="Documents")
@XmlElement(name = "Document")
private Document[] documents;
But this is what its serializing to:
<Documents>
<Documents>
.
.
.
</Documents>
<Documents>
.
.
.
</Documents>
</Documents>
Where the children nodes have the same name as the parent node. IS there a way to get the desired outcome?
to ensures the XML is serialized correctly with proper parent and child node names you just need to modify the Document class to include a wrapper element for the list of documents. here is a test code so you get the point
Document
Class
package com.stackoverflow.xmlserialization;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlType;
import java.util.List;
@XmlRootElement(name = "Documents")
@XmlType(name = "Document")
public class Document {
private String title;
private String content;
private List<Document> documents;
public Document() {
}
public Document(String title, String content) {
this.title = title;
this.content = content;
}
@XmlElement(name = "Title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@XmlElement(name = "Content")
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@XmlElement(name = "Document")
public List<Document> getDocuments() {
return documents;
}
public void setDocuments(List<Document> documents) {
this.documents = documents;
}
}
DocumentController
Class
package com.stackoverflow.xmlserialization;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
@RestController
public class DocumentController {
@GetMapping(value = "/documents", produces = "application/xml")
public String getDocuments() {
// Create a hardcoded list of Document objects
List<Document> documents = Arrays.asList(
new Document("Document 1 Title", "Document 1 Content"),
new Document("Document 2 Title", "Document 2 Content")
);
// Create a wrapper Document object to hold the list
Document wrapper = new Document();
wrapper.setDocuments(documents);
try {
// Initialize JAXB context and marshaller
JAXBContext context = JAXBContext.newInstance(Document.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// Serialize to XML
StringWriter sw = new StringWriter();
marshaller.marshal(wrapper, sw);
// Return the XML string
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
return "<error>Error generating XML</error>";
}
}
}
I've test the /documents
endpoint, and the returned xml is:
<Documents>
<Document>
<Content>Document 1 Content</Content>
<Title>Document 1 Title</Title>
</Document>
<Document>
<Content>Document 2 Content</Content>
<Title>Document 2 Title</Title>
</Document>
</Documents>
and this is the desired structure.