Reputation: 45
I have a list loaded with XML lines, which can come in any order as per the following ...
<MAIN_TAG>
<TAG_ONE>22</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>8888</TAG_FOUR>
<TAG_FIVE>arcdf</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>3</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>522</TAG_FOUR>
<TAG_FIVE>00561</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>10</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>200</TAG_FOUR>
<TAG_FIVE>ggggg</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>1</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>951</TAG_FOUR>
<TAG_FIVE>56756</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>35</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>071</TAG_FOUR>
<TAG_FIVE>ds15s</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>2</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>071</TAG_FOUR>
<TAG_FIVE>34534</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>40</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>45</TAG_FOUR>
<TAG_FIVE>4rsss</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>42</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>35</TAG_FOUR>
<TAG_FIVE>cdsss</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>20</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>10</TAG_FOUR>
<TAG_FIVE>dssss</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>30</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>1</TAG_FOUR>
<TAG_FIVE>dsdfe</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
I would like to be able to sort this Java list based on a tag passed in by the user. So the following would have been sorted by passing in to sort by 'TAG_ONE'...
<MAIN_TAG>
<TAG_ONE>1</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>951</TAG_FOUR>
<TAG_FIVE>56756</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>2</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>071</TAG_FOUR>
<TAG_FIVE>34534</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>3</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>522</TAG_FOUR>
<TAG_FIVE>00561</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>10</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>200</TAG_FOUR>
<TAG_FIVE>ggggg</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>20</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>10</TAG_FOUR>
<TAG_FIVE>dssss</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>22</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>8888</TAG_FOUR>
<TAG_FIVE>arcdf</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>30</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>1</TAG_FOUR>
<TAG_FIVE>dsdfe</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>35</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>071</TAG_FOUR>
<TAG_FIVE>ds15s</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>40</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>45</TAG_FOUR>
<TAG_FIVE>4rsss</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>42</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>35</TAG_FOUR>
<TAG_FIVE>cdsss</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
But would be good to have the option to sort by 'TAG_FOUR' for example.
Thank you in advance for any help.
Stacksamus
Upvotes: 2
Views: 1251
Reputation: 8509
Alternatively you can use xslt for this. You could parameterize the tag to sort, the sort order, type etc.. Howvever you need to have a root element. I gave Example
import java.io.File;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class Test {
public static void main(String[] args) throws Exception {
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("sort.xslt"));
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(new File("data.xml"));
transformer.setParameter("tagName", "TAG_ONE");
transformer.transform(text, new StreamResult(new File("output.xml")));
System.out.println("Done");
}
}
sort.xslt
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:param name="tagName" />
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates>
<xsl:sort data-type="number" select="*[name() = $tagName]" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 418655
Here is a complete solution.
First I define 2 very simple classes to represent the data in the XML: Wrapper
and MainTag
. The wrapper just wraps the MAIN_TAG
elements in a list, required by JAXB
. The MainTag
class just holds public properties, exactly as appearing in the input.
Once the input is read, I sort it by an arbitrarily chosen TAG (identified by an int index, 1 for TAG_ONE, 2 for TAG_TWO etc.). The sorting is implemented in the Wrapper.sort()
method which takes the tag as parameter to sort by.
Lastly I simply print out the result to the standard outpout, also using JAXB
.
Input is slightly modified (wrapped in a wrapper
tag):
<wrapper>
<MAIN_TAG>
<TAG_ONE>22</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>8888</TAG_FOUR>
<TAG_FIVE>arcdf</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
<TAG_ONE>3</TAG_ONE>
<TAG_TWO>2</TAG_TWO>
<TAG_THREE>junk</TAG_THREE>
<TAG_FOUR>522</TAG_FOUR>
<TAG_FIVE>00561</TAG_FIVE>
<TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<!-- ...and the rest which I omit here... -->
</wrapper>
The Wrapper and MainTag classes:
class Wrapper {
public List< MainTag > MAIN_TAG = new ArrayList<>();
public void sort(final int byTag) {
Collections.sort(MAIN_TAG, new Comparator< MainTag >() {
@Override
public int compare(MainTag m1, MainTag m2) {
switch (byTag) {
case 1: return m1.TAG_ONE.compareTo(m2.TAG_ONE);
case 2: return m1.TAG_TWO.compareTo(m2.TAG_TWO);
case 3: return m1.TAG_THREE.compareTo(m2.TAG_THREE);
case 4: return m1.TAG_FOUR.compareTo(m2.TAG_FOUR);
case 5: return m1.TAG_FIVE.compareTo(m2.TAG_FIVE);
case 6: return m1.TAG_SIX.compareTo(m2.TAG_SIX);
}
return 0;
}
});
}
}
class MainTag {
public Integer TAG_ONE;
public Integer TAG_TWO;
public String TAG_THREE;
public Integer TAG_FOUR;
public String TAG_FIVE;
public String TAG_SIX;
}
And finally how to use it:
Wrapper w = JAXB.unmarshal(new File("input.xml"), Wrapper.class);
w.sort(1);
JAXB.marshal(w, System.out);
Upvotes: 1