1

Is there a "standardized" way (i.e., code pattern, or, even better, open source library) in Java for dynamically flattening ("shredding") a hierarchical XML file, of large size and unknown structure, with output not redirected to an RDBMS but directly accessible?

I am looking at a transformation like the one mentioned in this question, but all the code examples I have seen use some SQL command to inject the flattened XML input to a database table, via an RDBMS (e.g., MySQL).

What I would like to do is progressively extract the XML data into a string, or, at least, into a text file, which could be post-processed afterwards, without going through any RDBMS.

EDIT:

After working further on the issue, there are a couple of solutions using XSLT (including a fully parameterizable one) in this question.

3
  • 1
    Is it even possible to shred an XML file of unknown structure? Commented Dec 13, 2011 at 22:40
  • I'd probably use StAX for the combination of speed and convenience, but that's a fairly generic suggestion (for a very very generic question.) Are you sure you can't outline the class of use cases you need to deal with with a few examples? Commented Dec 24, 2011 at 9:02
  • Sure. Detailed examples can be found in the XSLT version of this question, as per the edit above. Commented Dec 24, 2011 at 9:06

1 Answer 1

2

You could do it with JDOM (see example below, jdom.jar has to be on the classpath). But beware, the whole dom is in memory. If the XML is bigger you should use XSLT or a SAX parser.

import java.io.IOException;
import java.io.StringReader;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.junit.Test;

public class JDomFlatten {

@Test
public void testFlatten() {
    final String xml = "<grandparent name=\"grandpa bob\">"//
            + "<parent name=\"papa john\">"//
            + "<children>"//
            + "<child name=\"mark\" />"//
            + "<child name=\"cindy\" />"//
            + "</children>"//
            + "</parent>"//
            + "<parent name=\"papa henry\">"// 
            + "<children>" //
            + "<child name=\"mary\" />"//
            + "</children>"//
            + "</parent>" //
            + "</grandparent>";
    final StringReader stringReader = new StringReader(xml);
    final SAXBuilder builder = new SAXBuilder();
    try {
        final Document document = builder.build(stringReader);
        final Element grandparentElement = document.getRootElement();
        final StringBuilder outString = new StringBuilder();
        for (final Object parentElementObject : grandparentElement.getChildren()) {
            final Element parentElement = (Element) parentElementObject;
            for (final Object childrenElementObject : parentElement.getChildren()) {
                final Element childrenElement = (Element) childrenElementObject;
                for (final Object childElementObject : childrenElement.getChildren()) {
                    final Element childElement = (Element) childElementObject;

                    outString.append(grandparentElement.getAttributeValue("name"));
                    outString.append(" ");
                    outString.append(parentElement.getAttributeValue("name"));
                    outString.append(" ");
                    outString.append(childElement.getAttributeValue("name"));
                    outString.append("\n");
                }
            }

        }
        System.out.println(outString);

    } catch (final JDOMException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (final IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the code! The files I am looking at are indeed big, so JDOM is not an option and the contents are not previously known, which complicates things a lot. I have updated the original question to reflect this. Any more ideas are welcome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.