近日,工作中遇到一个有关XML文件内容进行排序的问题。经多方求教,加上本人的一点点努力,终于解决此问题。特此记录,以供其他朋友参详。
1. 问题描述
XML文档结构如下:
<?xml version="1.0" encoding="gb2312"?><?xml-stylesheet type="text/xsl" title="master" href="./../../ReportXSL/master_sppg.xsl"?><?xml-stylesheet type="text/xsl" title="detail" href="./../../ReportXSL/detail_sppg.xsl"?><?xreport processor="withub.common.stat.xreport.AppendSQL" cache="false"?><xreport id="80001" statBeginTime="2008-12-23 " statEndTime="2009-09-22 " statTime="2009-09-16"><result> <col> <col colspan="1" id="-1" rowspan="1"/> <col colspan="1" id="1" name="xx数" rowspan="1"/> <col colspan="1" id="2" name="xx数" rowspan="1"/> <col colspan="1" format="##.##" id="3" name="同期xx率" operator="(col[1]/col[2])*100" rowspan="1"/> <col colspan="1" id="4" name="xx数" rowspan="1"/> <col colspan="1" id="5" name="xx数" rowspan="1"/> <col colspan="1" id="6" name="上一期末xx数" rowspan="1"/> <col colspan="1" format="##.##" id="7" name="xx率" operator="(col[4]/(col[5]+col[6]))*100" rowspan="1"/> </col> <row id="$001"> <row code="1300" colspan="1" id="$001" name="" rowspan="1" startExpand="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1300" value="3234"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1300" value="3388"/> <col format="##.##" id="3" isLink="0" value="95.45454545"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1300" value="3234"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1300" value="3388"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1300" value="894"/> <col format="##.##" id="7" isLink="0" value="75.52545539"/> </row> <row id="$002"> <row code="1301" colspan="1" id="$002" name="XX中院" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1301" value="4596"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1301" value="5523"/> <col format="##.##" id="3" isLink="0" value="83.21564367"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1301" value="4596"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1301" value="5523"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1301" value="1422"/> <col format="##.##" id="7" isLink="0" value="66.17710583"/> </row> <row id="$003"> <row code="1302" colspan="1" id="$003" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1302" value="2907"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1302" value="3183"/> <col format="##.##" id="3" isLink="0" value="91.32893497"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1302" value="2907"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1302" value="3183"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1302" value="852"/> <col format="##.##" id="7" isLink="0" value="72.04460967"/> </row> <row id="$004"> <row code="1303" colspan="1" id="$004" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1303" value="3587"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1303" value="4444"/> <col format="##.##" id="3" isLink="0" value="80.71557156"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1303" value="3587"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1303" value="4444"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1303" value="757"/> <col format="##.##" id="7" isLink="0" value="68.96750625"/> </row> <row id="$005"> <row code="1304" colspan="1" id="$005" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1304" value="3828"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1304" value="4961"/> <col format="##.##" id="3" isLink="0" value="77.16186253"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1304" value="3828"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1304" value="4961"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1304" value="772"/> <col format="##.##" id="7" isLink="0" value="66.77132391"/> </row> <row id="$006"> <row code="1305" colspan="1" id="$006" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1305" value="2718"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1305" value="3884"/> <col format="##.##" id="3" isLink="0" value="69.97940268"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1305" value="2718"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1305" value="3884"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1305" value="334"/> <col format="##.##" id="7" isLink="0" value="64.43812233"/> </row> <row id="$007"> <row code="1306" colspan="1" id="$007" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1306" value="6471"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1306" value="7979"/> <col format="##.##" id="3" isLink="0" value="81.10038852"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1306" value="6471"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1306" value="7979"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1306" value="1328"/> <col format="##.##" id="7" isLink="0" value="69.52831202"/> </row> <row id="$008"> <row code="1307" colspan="1" id="$008" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1307" value="1352"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1307" value="1773"/> <col format="##.##" id="3" isLink="0" value="76.25493514"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1307" value="1352"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1307" value="1773"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1307" value="220"/> <col format="##.##" id="7" isLink="0" value="67.83743101"/> </row> <row id="$009"> <row code="1308" colspan="1" id="$009" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1308" value="12727"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1308" value="14326"/> <col format="##.##" id="3" isLink="0" value="88.8384755"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1308" value="12727"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1308" value="14326"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1308" value="2021"/> <col format="##.##" id="7" isLink="0" value="77.85526396"/> </row> <row id="$010"> <row code="1309" colspan="1" id="$010" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1309" value="4125"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1309" value="4851"/> <col format="##.##" id="3" isLink="0" value="85.03401361"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1309" value="4125"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1309" value="4851"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1309" value="1028"/> <col format="##.##" id="7" isLink="0" value="70.16499405"/> </row> <row id="$011"> <row code="1310" colspan="1" id="$011" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="0" url="ZB_CODE=ZB_1_C1&CBFYBS=$(CBFYBS)$" value="0"/> <col format="" id="2" isLink="0" url="ZB_CODE=ZB_1_C2&CBFYBS=$(CBFYBS)$" value="0"/> <col format="##.##" id="3" isLink="0" value="0"/> <col format="" id="4" isLink="0" url="ZB_CODE=ZB_1_1_C1&CBFYBS=$(CBFYBS)$" value="0"/> <col format="" id="5" isLink="0" url="ZB_CODE=ZB_1_1_C2&CBFYBS=$(CBFYBS)$" value="0"/> <col format="" id="6" isLink="0" url="ZB_CODE=ZB_1_1_C3&CBFYBS=$(CBFYBS)$" value="0"/> <col format="##.##" id="7" isLink="0" value="0"/> </row> <row id="$012"> <row code="1311" colspan="1" id="$012" name="XX市X处" rowspan="1"/> <col format="" id="1" isLink="1" url="ZB_CODE=ZB_1_C1&CBFYBS=1311" value="3751"/> <col format="" id="2" isLink="1" url="ZB_CODE=ZB_1_C2&CBFYBS=1311" value="5008"/> <col format="##.##" id="3" isLink="0" value="74.90015974"/> <col format="" id="4" isLink="1" url="ZB_CODE=ZB_1_1_C1&CBFYBS=1311" value="3751"/> <col format="" id="5" isLink="1" url="ZB_CODE=ZB_1_1_C2&CBFYBS=1311" value="5008"/> <col format="" id="6" isLink="1" url="ZB_CODE=ZB_1_1_C3&CBFYBS=1311" value="268"/> <col format="##.##" id="7" isLink="0" value="71.09552691"/> </row> </result> </xreport>
要求根据用户需求,对指定的某一列的值(如第六列,则根据每一个id=”6”的value值进行排序),指定的排序顺序,进行排序,然后根据该顺序,交换每个行(即节点row的位置)的位置
2.此重点在于如何把子节点col与其父节点进行关联,并且,当排序列的值相同时,不能去除重复的值,必须都参与排序。开始考虑用一般的排序方法,但是不能把父节点关联起来,最后经他人提醒,用TreeMap来排序,把col的值作为TreeMap的key,父节点作为value。但TreeMap会自动去掉重复值,因此,当col节点值相同时,他只去一个,为解决此问题,吧col值与父节点row的id联合作为key。解决此问题
3.主要java代码如下:
public void sortByTreeMap() throws Exception { XPathFactory factory = XPathFactory.newInstance(); XPath xpath = (XPath) factory.newXPath(); DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); // never forget this! DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("stat3.xml"); XPathExpression exprCol = xpath.compile("//row/col[@id='6']"); Object cols = exprCol.evaluate(doc, XPathConstants.NODESET); NodeList colNodes = (NodeList) cols; // 升序排序 Comparator comp = new Comparator() { //针对Float型的排序 /* public int compare(Object o1, Object o2) { Float f1 = (Float) o1; Float f2 = (Float) o2; if (f1 == null && f2 == null) { return 0; } else if (f1 == null) { return -1; } else if (f2 == null) { return 1; } else if (f1 == f2) { return 1; } else { return f1.compareTo(f2); } }*/ public int compare(Object o1, Object o2) { int i,j,k; String strA,strB; strA = (String)o1; strB = (String)o2; i = strA.lastIndexOf('-'); j = strB.lastIndexOf('-'); //此处解决,当col节点值相等时,根据其父节点的id值排序,以免相等值被TreeMap自动剔除 k = new Float(strA.substring(0, i)).compareTo(new Float(strB.substring(0, j))); if(k == 0) return new Float(strA.substring(i+2, strA.length())).compareTo(new Float(strB.substring(j+2, strB.length()))); else return k; } }; // 降序排列 Comparator compDesc = new Comparator() { public int compare(Object o1, Object o2) { int i,j,k; String strA,strB; strA = (String)o1; strB = (String)o2; i = strA.lastIndexOf('-'); j = strB.lastIndexOf('-'); k = new Float(strB.substring(0, j)).compareTo(new Float(strA.substring(0, i))); if(k == 0) return new Float(strB.substring(j+2, strB.length())).compareTo(new Float(strA.substring(i+2, strA.length()))); else return k; } }; // TreeMap treeMap = new TreeMap(comp); TreeMap treeMap = new TreeMap(compDesc); // Element resultElem = (Element) result.item(0) ; for (int i = 0; i < colNodes.getLength(); i++) { Element colElem = (Element) colNodes.item(i); Element parentElem = (Element) colElem.getParentNode(); //把col的值和对应的row 的id值组成一个字符串,以解决自动去除重复值的问题 treeMap.put(colElem.getAttribute("value") + "-" + parentElem.getAttribute("id"), parentElem); } Iterator iter = treeMap.entrySet().iterator(); XPathExpression exprResult = xpath.compile("//result"); Element resultNode = (Element) exprResult.evaluate(doc, XPathConstants.NODE); int xuhao = 0; String temp = ""; //排序后,交换行其父节点位置 while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Element newNode = (Element)entry.getValue() ; resultNode.appendChild(newNode); } saveXML("stat3-paixuDesc.xml", doc, "gb2312") ; } 本文同步发表到本人博客:http://blog.csdn.net/antti_king/archive/2009/09/16/4557582.aspx
相关资源:java 大文件 多字段排序