从制造到创造
软件工程师成长之路
posts - 292,  comments - 96,  trackbacks - 0
需求:
对XML中的特定内容进行排序:
原始XML:
<?xml version="1.0" encoding="UTF-8"?>
<hostgateway>
    
<header>
        
    
</header>
    
<line no="1">
        
<msgHeader />
        
<msgBody>
            
<data id="FEE_AMT_4" value="0000000000" />
            
<data id="FEE_TOTAL_2" value="0000000000" />
            
<data id="FEE_AMT_3" value="0000000000" />
            
<data id="FEE_TOTAL_1" value="0000000000" />
            
<data id="FEE_AMT_2" value="0000000000" />
            
<data id="FEE_AMT_1" value="0000000000" />
            
        
</msgBody>
    
</line>
</hostgateway>

这里我们可以看到,msgBody节点的数据data部分没有按照id进行排序,而很多id是相同的,只是后面有后缀_1、_2之类的,我们的目的是将所有的msgBody节点下的内容按照id的内容进行排序,注意这里的id和value是配对的,所以要用对象封装起来。

1、用Dom4j读取xml:
            // 使用 SAXReader 解析 XML 文档 
           SAXReader saxReader 
= new SAXReader();
            Document document 
= saxReader.read(new File(
                    
"c:/catalog/rtnP4_JCA3.xml"));

            
// inputXml 是从 c:/catalog/catalog.xml 创建的 java.io.File。
            
// 使用 XPath 表达式从 article 元素中获得 level 节点列表。
            
// 如果 level 属性值是“Intermediate”则改为“Introductory”。
            List list = document.selectNodes("//msgBody/data/@id");
            Iterator iter 
= list.iterator();
            
while (iter.hasNext()) {
                Attribute at 
= (Attribute) iter.next();
                String pathStr 
= "hostgateway/line/msgBody/data[@id='"
                        
+ at.getText() + "']/@value";
                System.out.println(pathStr);
                String a 
= document.valueOf(pathStr);
                System.out.println(
"value: " + a);
                data 
= new Data();
                data.setId(at.getText());
                data.setValue(a);
                listBody.add(data);
            }
注:
1、直接用SAXReader读取XML文件,传入参数为File;
2、可以通过document.selectNodes("")方式,传入XPath路径,得到ID的List;
3、通过document.valueOf("xxx")可以直接得到某个属性的值。

2、写XML
            /** 建立document对象 */
            Document document 
= DocumentHelper.createDocument();
            
/** 建立XML文档的根hostgateway */
            Element rootElement 
= document.addElement("hostgateway");
            
/** 加入第一个head节点 */
            Element headElement 
= rootElement.addElement("header");
            
/** 加入action节点 */
            Element actionElement 
= headElement.addElement("action");
            
/** 加入type参数内容 */
            actionElement.addAttribute(
"type""transaction");
            actionElement.addAttribute("type""transaction");
说明:
A、先通过DocumentHelper创建一个Document对象;
B、然后建立根节点;
C、再在根节点上增加子节点;
D、通过addAttribute增加属性;如果有多个属性可继续使用addAttribute方法;

生成XML文件
    /**
     * XML的编码方式为本地ANSI
     * 
     * 
@param document
     * 
@param filename
     * 
@throws IOException
     
*/
    
private static void writerXMLANSI(Document document, String filename)
            
throws IOException {

        OutputFormat format 
= OutputFormat.createPrettyPrint();
        XMLWriter writer 
= new XMLWriter(new FileWriter(filename), format);
        writer.write(document);
        writer.close();
    }

    
/**
     * XML的编码方式为UTF-8
     * 
     * 
@param document
     * 
@param filename
     * 
@throws IOException
     
*/
    
private static void writerXMLUTF8(Document document, String filename)
            
throws IOException {
        OutputFormat format 
= OutputFormat.createPrettyPrint();
        FileOutputStream fos 
= new FileOutputStream(new File(filename));
        XMLWriter writer 
= new XMLWriter(fos, format);
        writer.write(document);
        writer.close();
    }

通过 FileWriter 创建的XML生成的编码格式在简体中文环境会是GBK格式,如果想保存为编码格式为UTF-8,则必须使用FileOutputStream。

完整代码:
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * 
@author XL
 * 
 
*/
public class SortedXML {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        create();
    }    

    
public static void create() {
        
try {
            
/** 建立document对象 */
            Document document 
= DocumentHelper.createDocument();

            
/** 建立XML文档的根hostgateway */
            Element rootElement 
= document.addElement("hostgateway");

            
/** 加入第一个head节点 */
            Element headElement 
= rootElement.addElement("header");

            
/** 加入action节点 */
            Element actionElement 
= headElement.addElement("action");

            
/** 加入type参数内容 */
            actionElement.addAttribute(
"type""transaction");

            
/** 加入data节点 */
            List listHead 
= initListHead();
            insertData(headElement, listHead);

            
/** 加入第二个节点line */
            Element lineElement 
= rootElement.addElement("line");
            lineElement.addAttribute(
"no""1");

            
/** 加入msgHeader节点 */
            lineElement.addElement(
"msgHeader");

            
/** 加入msgBody节点 */
            Element msgBodyElement 
= lineElement.addElement("msgBody");

            
/** 加入data节点 */
            List listBody 
= initListBody();
            insertData(msgBodyElement, listBody);

            
/** 加入type参数内容 */

            
/** 格式化输出 */
            writerXMLANSI(document, 
"c:/catalog/rtnP4_JCA3_40.xml");
            writerXMLUTF8(document, 
"c:/catalog/rtnP4_JCA3_41.xml");
        } 
catch (IOException e) {
            e.printStackTrace();
        }
    }

    
/**
     * XML的编码方式为本地ANSI
     * 
     * 
@param document
     * 
@param filename
     * 
@throws IOException
     
*/
    
private static void writerXMLANSI(Document document, String filename)
            
throws IOException {

        OutputFormat format 
= OutputFormat.createPrettyPrint();
        XMLWriter writer 
= new XMLWriter(new FileWriter(filename), format);
        writer.write(document);
        writer.close();
    }

    
/**
     * XML的编码方式为UTF-8
     * 
     * 
@param document
     * 
@param filename
     * 
@throws IOException
     
*/
    
private static void writerXMLUTF8(Document document, String filename)
            
throws IOException {
        OutputFormat format 
= OutputFormat.createPrettyPrint();
        FileOutputStream fos 
= new FileOutputStream(new File(filename));
        XMLWriter writer 
= new XMLWriter(fos, format);
        writer.write(document);
        writer.close();
    }

    
/**
     * 初始化XML表头
     * 
     * 
@return
     
*/
    
private static List initListHead() {
        List listHead 
= new ArrayList();
        listHead.add(
new Data("sessionId""CSIrzFmHlZ8Lwcc_okMucJrH_iZ04975"));
        listHead.add(
new Data("applicationId""CSI"));
        listHead.add(
new Data("luType""LU62"));
        listHead.add(
new Data("transactionId""P4_JCA3"));

        
return listHead;
    }

    
/**
     * 获得原始XML中的msgBody中的
     * 
     * 
@return
     
*/
    
private static List initListBody() {

        List listBody 
= new ArrayList();

        
try {
            Data data 
= null;
            
// 使用 SAXReader 解析 XML 文档 catalog.xml:
            SAXReader saxReader = new SAXReader();
            Document document 
= saxReader.read(new File(
                    
"c:/catalog/rtnP4_JCA3.xml"));

            
// inputXml 是从 c:/catalog/catalog.xml 创建的 java.io.File。
            
// 使用 XPath 表达式从 article 元素中获得 level 节点列表。
            
// 如果 level 属性值是“Intermediate”则改为“Introductory”。
            List list = document.selectNodes("//msgBody/data/@id");
            Iterator iter 
= list.iterator();
            
while (iter.hasNext()) {
                Attribute at 
= (Attribute) iter.next();
                String pathStr 
= "hostgateway/line/msgBody/data[@id='"
                        
+ at.getText() + "']/@value";
                System.out.println(pathStr);
                String a 
= document.valueOf(pathStr);
                System.out.println(
"value: " + a);
                data 
= new Data();
                data.setId(at.getText());
                data.setValue(a);
                listBody.add(data);
            }

            sortVO(listBody);

        } 
catch (DocumentException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            
return null;
        }

        
return listBody;
    }

    
/**
     * 将List中的对象按照ID进行排序
     * 
     * 
@param list
     
*/
    
public static void sortVO(List list) {
        Collections.sort(list);
    }

    
/**
     * 将List中的Data对象增加到节点中
     * 
     * 
@param headElement
     * 
@param list
     
*/
    
public static void insertData(Element headElement, List list) {
        
int size = list.size();
        Element dataElement 
= null;
        Data data 
= null;
        
for (int i = 0; i < size; i++) {
            data 
= (Data) list.get(i);
            dataElement 
= headElement.addElement("data");
            dataElement.addAttribute(
"id", data.getId());// 增加第一个属性
            dataElement.addAttribute("value", data.getValue());// 增加第二个属性
        }
    }

}

/**
 * Data对象,实现Comparable接口
 * 
 * 
@author XL
 * 
 
*/
class Data implements Comparable {
    
private String id;
    
private String value;
    
public Data() {
    }

    
public Data(String id, String value) {
        
super();
        
this.id = id;
        
this.value = value;
    }

    
public String getId() {
        
return id;
    }
    
public void setId(String id) {
        
this.id = id;
    }
    
public String getValue() {
        
return value;
    }
    
public void setValue(String value) {
        
this.value = value;
    }
    
public int compareTo(Object o) {
        Data d 
= (Data) o;
        
return this.getId().compareTo(d.getId());
    }
}

输出结果:
<?xml version="1.0" encoding="UTF-8"?>

<hostgateway>
  
<header>
    
<action type="transaction"/>
    
  
</header>
  
<line no="1">
    
<msgHeader/>
    
<msgBody>
      
<data id="AP-DATE" value=""/>
      
<data id="AP-STUS" value="A()"/>
      
<data id="APR1" value="13.07"/>
      
<data id="APR2" value="15.24"/>
      
<data id="APR3" value="16.89"/>
      
<data id="APR4" value="00.00"/>
      
<data id="AP_AMT" value="5000"/>
      
    
</msgBody>
  
</line>
</hostgateway>

参考:
1、dom4j 写UTF-8的xml乱码问题
2、dom4j的utf-8解决方法
posted on 2008-08-20 15:14 CoderDream 阅读(952) 评论(0)  编辑  收藏 所属分类: 学习笔记

只有注册用户登录后才能发表评论。


网站导航:
 

<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿(9)

我参与的团队

随笔分类(245)

随笔档案(239)

文章分类(3)

文章档案(3)

收藏夹(576)

友情链接

搜索

  •  

积分与排名

  • 积分 - 456297
  • 排名 - 114

最新评论

阅读排行榜

评论排行榜