<p>I'd like to store a properties file as XML.  Is there a way to sort the keys when doing this so that the generated XML file will be in alphabetical order?  </p>

<pre><code>String propFile = "/path/to/file";
Properties props = new Properties();
/*set some properties here*/
try {
    FileOutputStream xmlStream = new FileOutputStream(propFile);
    /*this comes out unsorted*/
    props.storeToXML(xmlStream,"");
} catch (IOException e) {
    e.printStackTrace();
}
</code></pre>

[{'answer_id': 54303, 'author': 'samjudson', 'author_id': 1908, 'author_profile': 'https://Stackoverflow.com/users/1908', 'pm_score': 1, 'selected': False, 'text': '<p>java.util.Properties is based on Hashtable, which does not store its values in alphabetical order, but in order of the hash of each item, that is why you are seeing the behaviour you are.</p>\n'}, {'answer_id': 54308, 'author': 'Stu Thompson', 'author_id': 2961, 'author_profile': 'https://Stackoverflow.com/users/2961', 'pm_score': 1, 'selected': False, 'text': "<p>java.util.Properties is a subclass of  java.util.<strong>Hashtable</strong>.  ('Hash', being the key here.)You'd have to come up with your own customer implementation based on something that keeps/defines order...like a TreeMap.</p>\n"}, {'answer_id': 54316, 'author': 'ScArcher2', 'author_id': 1310, 'author_profile': 'https://Stackoverflow.com/users/1310', 'pm_score': 2, 'selected': False, 'text': '<p>You could sort the keys first, then loop through the items in the properties file and write them to the xml file.</p>\n\n<pre><code>public static void main(String[] args){\n        String propFile = "/tmp/test2.xml";\n        Properties props = new Properties();\n        props.setProperty("key", "value");\n        props.setProperty("key1", "value1");\n        props.setProperty("key2", "value2");\n        props.setProperty("key3", "value3");\n        props.setProperty("key4", "value4");\n\n        try {\n            BufferedWriter out = new BufferedWriter(new FileWriter(propFile));\n            List&lt;String&gt; list = new ArrayList&lt;String&gt;();\n            for(Object o : props.keySet()){\n                list.add((String)o);\n            }\n            Collections.sort(list);\n            out.write("&lt;?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?&gt;\\n");\n            out.write("&lt;!DOCTYPE properties SYSTEM \\"http://java.sun.com/dtd/properties.dtd\\"&gt;\\n");\n            out.write("&lt;properties&gt;\\n");\n            out.write("&lt;comment/&gt;\\n");\n            for(String s : list){\n                out.write("&lt;entry key=\\"" + s + "\\"&gt;" + props.getProperty(s) + "&lt;/entry&gt;\\n");\n            }\n            out.write("&lt;/properties&gt;\\n");\n            out.flush();\n            out.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n</code></pre>\n'}, {'answer_id': 54382, 'author': 'Jay R.', 'author_id': 5074, 'author_profile': 'https://Stackoverflow.com/users/5074', 'pm_score': 0, 'selected': False, 'text': "<p>You could try this:</p>\n\n<p>Make a new class that does what java.util.XMLUtils does but in the save method change this:</p>\n\n<pre><code>Set keys = props.keySet();\nIterator i = keys.iterator();\n</code></pre>\n\n<p>to</p>\n\n<pre><code>Set keys = props.keySet();\nList&lt;String&gt; newKeys = new ArrayList&lt;String&gt;();\nfor(Object key : keys)\n{\n   newKeys.add(key.toString());\n}\nCollections.sort(newKeys);\nIterator i = newKeys.iterator();\n</code></pre>\n\n<p>Extend properties and override the Properties class storeToXML method to call your new class's save method.</p>\n"}, {'answer_id': 54399, 'author': 'Tim Frey', 'author_id': 1471, 'author_profile': 'https://Stackoverflow.com/users/1471', 'pm_score': -1, 'selected': False, 'text': '<p>Why do you want the XML file to be sorted in the first place?  Presumably, there is another piece of code that reads the file and puts the data in another Properties object.  Do you want to do this so you can manually find and edit entries in the XML file?</p>\n'}, {'answer_id': 54402, 'author': 'Tom Hawtin - tackline', 'author_id': 4725, 'author_profile': 'https://Stackoverflow.com/users/4725', 'pm_score': 2, 'selected': False, 'text': '<p>The simplest hack would be to override keySet. A bit of a hack, and not guaranteed to work in future implementations:</p>\n\n<pre><code>new Properties() {\n    @Override Set&lt;Object&gt; keySet() {\n        return new TreeSet&lt;Object&gt;(super.keySet());\n    }\n}\n</code></pre>\n\n<p>(Disclaimer: I have not even tested that it compiles.)</p>\n\n<p>Alternatively, you could use something like XSLT to reformat the produced XML.</p>\n'}, {'answer_id': 54454, 'author': 'erickson', 'author_id': 3474, 'author_profile': 'https://Stackoverflow.com/users/3474', 'pm_score': 6, 'selected': True, 'text': '<p>Here\'s a quick and dirty way to do it:</p>\n\n<pre><code>String propFile = "/path/to/file";\nProperties props = new Properties();\n\n/* Set some properties here */\n\nProperties tmp = new Properties() {\n  @Override\n  public Set&lt;Object&gt; keySet() {\n    return Collections.unmodifiableSet(new TreeSet&lt;Object&gt;(super.keySet()));\n  }\n};\n\ntmp.putAll(props);\n\ntry {\n    FileOutputStream xmlStream = new FileOutputStream(propFile);\n    /* This comes out SORTED! */\n    tmp.storeToXML(xmlStream,"");\n} catch (IOException e) {\n    e.printStackTrace();\n}\n</code></pre>\n\n<p>Here are the caveats:</p>\n\n<ul>\n<li>The tmp Properties (an anonymous\nsubclass) doesn\'t fulfill the\ncontract of Properties.</li>\n</ul>\n\n<p>For example, if you got its <code>keySet</code> and tried to remove an element from it, an exception would be raised. So, don\'t allow instances of this subclass to escape! In the snippet above, you are never passing it to another object or returning it to a caller who has a legitimate expectation that it fulfills the contract of Properties, so it is safe.</p>\n\n<ul>\n<li>The implementation of\nProperties.storeToXML could change,\ncausing it to ignore the keySet\nmethod.</li>\n</ul>\n\n<p>For example, a future release, or OpenJDK, could use the <code>keys()</code> method of <code>Hashtable</code> instead of <code>keySet</code>. This is one of the reasons why classes should always document their "self-use" (Effective Java Item 15). However, in this case, the worst that would happen is that your output would revert to unsorted.</p>\n\n<ul>\n<li>Remember that the Properties storage\nmethods ignore any "default"\nentries.</li>\n</ul>\n'}, {'answer_id': 3253071, 'author': 'Espen', 'author_id': 392356, 'author_profile': 'https://Stackoverflow.com/users/392356', 'pm_score': 4, 'selected': False, 'text': '<p>Here\'s a way to produce sorted output for both store <code>Properties.store(OutputStream out, String comments)</code> and <code>Properties.storeToXML(OutputStream os, String comment)</code>:</p>\n\n<pre><code>Properties props = new Properties() {\n    @Override\n    public Set&lt;Object&gt; keySet(){\n        return Collections.unmodifiableSet(new TreeSet&lt;Object&gt;(super.keySet()));\n    }\n\n    @Override\n    public synchronized Enumeration&lt;Object&gt; keys() {\n        return Collections.enumeration(new TreeSet&lt;Object&gt;(super.keySet()));\n    }\n};\nprops.put("B", "Should come second");\nprops.put("A", "Should come first");\nprops.storeToXML(new FileOutputStream(new File("sortedProps.xml")), null);\nprops.store(new FileOutputStream(new File("sortedProps.properties")), null);\n</code></pre>\n'}, {'answer_id': 17982586, 'author': 'Serg', 'author_id': 105037, 'author_profile': 'https://Stackoverflow.com/users/105037', 'pm_score': 0, 'selected': False, 'text': '<p>Here is another solution:</p>\n\n<pre><code>public static void save_sorted(Properties props, String filename) throws Throwable {\n    FileOutputStream fos = new FileOutputStream(filename);\n    Properties prop_sorted = new Properties() {\n        @Override\n        public Set&lt;String&gt; stringPropertyNames() {\n            TreeSet&lt;String&gt; set = new TreeSet&lt;String&gt;();\n            for (Object o : keySet()) {\n                set.add((String) o);\n            }\n            return set;\n        }\n    };\n    prop_sorted.putAll(props);\n    prop_sorted.storeToXML(fos, "test xml");\n}\n</code></pre>\n'}, {'answer_id': 23092108, 'author': 'trevorsky', 'author_id': 3203998, 'author_profile': 'https://Stackoverflow.com/users/3203998', 'pm_score': 2, 'selected': False, 'text': "<p>In my testing, the other answers to this question don't work properly on AIX. My particular test machine is running this version:</p>\n\n<blockquote>\n  <p>IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 AIX ppc64-64 jvmap6460sr9-20110624_85526</p>\n</blockquote>\n\n<p>After looking through the implementation of the <code>store</code> method, I found that it relies upon <code>entrySet</code>. This method works well for me.</p>\n\n<pre><code>public static void saveSorted(Properties props, FileWriter fw, String comment) throws IOException {\n    Properties tmp = new Properties() {\n        @Override\n        public Set&lt;Object&gt; keySet() {\n            return Collections.unmodifiableSet(new TreeSet&lt;Object&gt;(super.keySet()));\n        }\n\n        @Override\n        public Set&lt;java.util.Map.Entry&lt;Object,Object&gt;&gt; entrySet() {\n            TreeSet&lt;java.util.Map.Entry&lt;Object,Object&gt;&gt; tmp = new TreeSet&lt;java.util.Map.Entry&lt;Object,Object&gt;&gt;(new Comparator&lt;java.util.Map.Entry&lt;Object,Object&gt;&gt;() {\n                @Override\n                public int compare(java.util.Map.Entry&lt;Object, Object&gt; entry1, java.util.Map.Entry&lt;Object, Object&gt; entry2) {\n                    String key1 = entry1.getKey().toString();\n                    String key2 = entry2.getKey().toString();\n                    return key1.compareTo(key2);\n                }\n            });\n\n            tmp.addAll(super.entrySet());\n\n            return Collections.unmodifiableSet(tmp);\n        }\n\n        @Override\n        public synchronized Enumeration&lt;Object&gt; keys() {\n            return Collections.enumeration(new TreeSet&lt;Object&gt;(super.keySet()));\n        }\n\n        @Override\n        public Set&lt;String&gt; stringPropertyNames() {\n            TreeSet&lt;String&gt; set = new TreeSet&lt;String&gt;();\n            for(Object o : keySet()) {\n                set.add((String)o);\n            }\n            return set;\n        }\n    };\n\n    tmp.putAll(props);\n    tmp.store(fw, comment);\n}\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/54295', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5084/']