Java关于XML文档排序的问题

近日,工作中遇到一个有关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") ;
}


本文同步发表到本人CSDN博客:http://blog.csdn.net/antti_king/archive/2009/09/16/4557582.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值