0

My aim is to generate a tree structure in an XML file from a nested ArrayList containing File objects. I constructed the ArrayList by scanning a directory structure on my harddisk.

I want the XML file to look similar to the following:

<root>
     <layer1 name="">
        <layer2 name="">
           <layer3 name=""></layer3>
        </layer2>
     <layer1>
</root>

the XML should simply represent the hierarchical order of my folders and the name-attributes should be filled with the folder names.

Is there a simple way to realize this in Java? Thanks in advance!

1
  • There are a lot of ways to do it; if you decide which API you want to use (DOM, JDOM, code it all by hand, etc.) it would narrow down your choices. Commented Jan 16, 2015 at 13:14

2 Answers 2

1

I have a solution using a library that supports creation of XML via XPath like expression. (I am affiliated with that project)

public class CreateXML {

    public static void main(String[] args) {
       List<String> fileEntries = Arrays.asList("/path1/path2/file.txt","/path1/path3/path4/file2.txt","/path5/file3.txt");
       DOMAccess domAccess = new XBProjector().projectEmptyDocument(DOMAccess.class);
       for (String entry:fileEntries) {
       String xpath="root";
            int i=0;
           for (String s:(entry.replaceFirst("\\/", "")).split("\\/")) {
               xpath+="/layer"+(++i)+"[@name='"+s+"']";
           }
           System.out.println(xpath);
           domAccess.create(xpath, "");
       }
       System.out.println(domAccess.asString());
    }
}

First thepaths are transformed to a xpath, then elments are created by these paths. The program prints out:

root/layer1[@name='path1']/layer2[@name='path2']/layer3[@name='file.txt']
root/layer1[@name='path1']/layer2[@name='path3']/layer3[@name='path4']/layer4[@name='file2.txt']

root/layer1[@name='path5']/layer2[@name='file3.txt']
<root>
  <layer1 name="path1">
    <layer2 name="path2">
      <layer3 name="file.txt"/>
    </layer2>
    <layer2 name="path3">
      <layer3 name="path4">
        <layer4 name="file2.txt"/>
      </layer3>
    </layer2>
  </layer1>
  <layer1 name="path5">
    <layer2 name="file3.txt"/>
  </layer1>
</root>
Sign up to request clarification or add additional context in comments.

Comments

0

You'll need only the top-most file in your hierarchy for this. If you don't know which is you can first sort your list, this will put the top-most file at the first position.

String parseFile(File file, int layer) {
    StringBuilder result = new StringBuilder();
    if(file.isDirectory()) {
        if(layer == 0) {
            result.append("<root>");
            for(File childFile : file.listFiles()) {
                result.append(parseFile(childFile, layer + 1));
            }
            result.append("</root>");
        }
        result.append("<layer"+layer+" name=\""+file.getName()+"\">");
        for(File childFile : file.listFiles()) {
           result.append(parseFile(childFile, layer + 1));
        }
        result.append("</layer"+layer+">");
    }
    return result.toString();
}

This will go on until the leaf directories, if you intend to parse strictly the files on your list you'll need to test:

String parseFile(List<File> originalFileList, File file, int layer) {
    StringBuilder result = new StringBuilder();
    if(file.isDirectory()) {
        if(layer == 0) {
            result.append("<root>");
            for(File childFile : file.listFiles()) {
                if(originalFileList.contains(childFile)) {
                   result.append(parseFile(originalFileList, childFile, layer + 1));
                }
            }
            result.append("</root>");
        } else {
            result.append("<layer"+layer+" name=\""+file.getName()+"\">");
            for(File childFile : file.listFiles()) {
                if(originalFileList.contains(childFile)) {
                   result.append(parseFile(originalFileList, childFile, layer + 1));
                }
            }
            result.append("</layer"+layer+">");
        }
    }
    return result.toString();
}

1 Comment

XML should never be created manually by string concatenation. What if a path contains a char that needs to be escaped in XML? What about the file encoding?

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.