Search code examples
javaxmlxsddspace

Problem in converting Java objects to XML based on a given XSD file


I am generating a custom XML export in DSpace 5.2. The item that is to be exported as an XML file has an array of metadata values. The values must appear in the XML file as the given XSD file defines their hierarchy. I add the values based on the XSD order into the XML, but some XML tags are in an order different from the insertion order.

More details

The approach I am using is, at first, move the array of metadata values into a map. The keys of the map are the metadata field names. Then, based on the XSD, I get an appropriate value from the map and generate an XML element like this:

import org.dspace.content.Metadatum;
import org.w3c.dom.Element;
import org.w3c.dom.Document;

public class DSpaceXML implements Serializable {
// A member variable
private Document doc;

// A DSpace built-in function used to export an item to an XML
    public final void addItem(Item item) throws Exception {

        // Initialize this.doc
        Element rootElement = doc.createElement("root");
        Element higherElement = doc.createElement("higher-element");
        Element lowerElement = doc.createElement("lower-element");

        insertMetadataAsChildOfElement(higherElement, "child-of-higher", "dc.childOfHigher");
        rootElement.appendChild(higherElement);

        insertMetadataAsChildOfElement(lowerElement, "child-of-lower", "dc.childOfLower");
        rootElement.appendChild(lowerElement);

        // stuff to generate other elements of the XML
    }

    private void insertMetadataAsChildOfElement(Element parentElement, String childElementName,
            String key) {

        Element childElement;

        <Metadatum> metadatumList = (<Metadatum>) metadataMap.get(key);

        childElement = createElement(childElementName, metadatum.value);

        parentElement.appendChild(childElement);
    }

    private Element createElement(String name, String value) {
        Element el = doc.createElement(name);
        el.appendChild(doc.createTextNode(value));
        return el;
    }
}

I expect an XML like this:

<root>
     <higher-element>
         <child-of-higher>Value1</child-of-higher>
     </higher-element>
     <lower-element>
         <child-of-lower>Value2</child-of-lower>
     </lower-element>
     <another-element-1/>
     ....
     <another-element-n/>
</root>

What I get is like this (<lower-element> is before <higher-element>):

<root>
     <lower-element>
         <child-of-lower>Value2</child-of-lower>
     </lower-element>
     <another-element-1/>
     ....
     <another-element-k/>
     <higher-element>
         <child-of-higher>Value1</child-of-higher>
     </higher-element>
     <another-element-k-plus-1/>
     ....
     <another-element-n/>
</root>

I cannot figure out why this happens while rootElement.appendChild(higherElement) is called before rootElement.appendChild(lowerElement). Also, I would appreciate if someone let me know if my approach is the best one for generating an XML from an XSD.


Solution

  • I figured out that I had a bug in my code. Due to checking a lot of metadata values, many lines after the line rootElement.appendChild(lowerElement), I had a line rootElement.appendChild(higherElement), so it overrode the former hierarchy of XML elements. As a result <higher-element> appeared after <lower-element>. But about the second part of my question, I will be happy if someone would tell me about the best practices of generating an XML based on an XSD regarding the limitations of DSpace 5.