1 asXML方法概述
在使用Dom4j的時候,有時候需要將一個Document對象或Element對象轉換爲一個String,可以直接調用Document.asXML()方法來實現。
其中:Element對象的element.asXML();指的是這個節點(元素)的開始到結束包含的內容組成String;Document 對象的document.asXML()就是將整個文件組成一個String。
但是,在使用這個法法的時候出現了以下問題:例如,我原始xml報文中有一節點<SN></SN>,其節點信息中無內容,正常顯示即爲“<SN></SN>”;但是在調用了Document對象或Element對象的asXML方法之後,發現其節點變爲:“<SN/>”,其節點自封閉;如果是一般信息傳輸可能沒有問題,但是如果要對這一段報文做加解密處理時:甲發送報文時爲完整的節點信息,如“<SN></SN>”;可是乙方接收報文後對報文進行驗籤的時候,如果使用了asXML方法,則得到的原始數據可能就會發生變化(例如:部分內容由<SN></SN>變爲<SN/>),此時會造成驗籤或者減密失敗;
2 解決方案
自己封裝asXml方法,解決節點內容爲空時的自封閉問題。主要代碼是:format.setExpandEmptyElements(true); 若爲false則自閉合。
// 轉換爲標準格式(避免自閉合的問題)
private static String asXml(Element body) {
OutputFormat format = new OutputFormat();
format.setEncoding("UTF-8");
format.setExpandEmptyElements(true);
StringWriter out = new StringWriter();
XMLWriter writer = new XMLWriter(out, format);
try {
writer.write(body);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
return out.toString();
}
3 java代碼示例
package xin.dreaming.dom4j;
import java.io.IOException;
import java.io.StringWriter;
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.XMLWriter;
import org.junit.Test;
public class Dom4jTest {
@Test
public void dom4jTest() throws DocumentException {
String xmlStr = "<?xml version=\"1.0\" encoding=\"GBK\"?><GZELINK><INFO><TRX_CODE>200001</TRX_CODE><VERSION>05</VERSION><DATA_TYPE>2</DATA_TYPE><LEVEL>0</LEVEL><REQ_SN>1010411008171128</REQ_SN><RET_CODE>0000</RET_CODE><ERR_MSG>處理成功</ERR_MSG><SIGNED_MSG>KadnQtpIVovVLmeLCF810dlKCQrpWNgR5jVt0P9ygEp8yjnrhr5nd57dn4Z9bJJzlY2tqyc9HqbgOVY00mycak2HOpR3rq0ntgls8dAmRhCIKHkifVwamIfxG/KqecHs5QW4QjK25ig7nxzog0JknDoASeaiAI6DpKsmbpm0edrwRXamnpo6UDiW9POLoqrQX15jEXpWkPIMNjx5ISH/9GsAi8fr8p6Un+ShdEcKtIpUGBqn1di3mDC7pCV3MBvzcq+dCl9speHdJOQ9ZLsPs2gJkZs0pOeh7OlIP+WGbCRuv7SzV146gjEN40YeYbyvJmN9z1kOXBrOi2GIR3yX5g==</SIGNED_MSG></INFO><BODY><QUERY_TRANS><QUERY_SN>1711271010346380</QUERY_SN><QUERY_REMARK></QUERY_REMARK></QUERY_TRANS><RET_DETAILS><RET_DETAIL><SN></SN><PAY_STATUS></PAY_STATUS><RET_CODE>0090</RET_CODE><ERR_MSG>原交易未找到</ERR_MSG></RET_DETAIL></RET_DETAILS></BODY></GZELINK>";
//原xml報文內容
System.out.println(xmlStr);
System.out.println("------------------------------------------------------------------------------");
Document document = DocumentHelper.parseText(xmlStr);
// 獲取body節點
Element body = document.getRootElement().element("BODY");
//使用asXML方法轉換,打印body內容
System.out.println(body.asXML());
System.out.println("------------------------------------------------------------------------------");
//使用自己封裝的axXml(Element element)方法,打印body節點內容
System.out.println(asXml(body));
}
// 轉換爲標準格式(避免自閉合的問題)
private static String asXml(Element body) {
OutputFormat format = new OutputFormat();
format.setEncoding("UTF-8");
format.setExpandEmptyElements(true);
StringWriter out = new StringWriter();
XMLWriter writer = new XMLWriter(out, format);
try {
writer.write(body);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
return out.toString();
}
}
輸出結果:
<?xml version="1.0" encoding="GBK"?><GZELINK><INFO><TRX_CODE>200001</TRX_CODE><VERSION>05</VERSION><DATA_TYPE>2</DATA_TYPE><LEVEL>0</LEVEL><REQ_SN>1010411008171128</REQ_SN><RET_CODE>0000</RET_CODE><ERR_MSG>處理成功</ERR_MSG><SIGNED_MSG>KadnQtpIVovVLmeLCF810dlKCQrpWNgR5jVt0P9ygEp8yjnrhr5nd57dn4Z9bJJzlY2tqyc9HqbgOVY00mycak2HOpR3rq0ntgls8dAmRhCIKHkifVwamIfxG/KqecHs5QW4QjK25ig7nxzog0JknDoASeaiAI6DpKsmbpm0edrwRXamnpo6UDiW9POLoqrQX15jEXpWkPIMNjx5ISH/9GsAi8fr8p6Un+ShdEcKtIpUGBqn1di3mDC7pCV3MBvzcq+dCl9speHdJOQ9ZLsPs2gJkZs0pOeh7OlIP+WGbCRuv7SzV146gjEN40YeYbyvJmN9z1kOXBrOi2GIR3yX5g==</SIGNED_MSG></INFO><BODY><QUERY_TRANS><QUERY_SN>1711271010346380</QUERY_SN><QUERY_REMARK></QUERY_REMARK></QUERY_TRANS><RET_DETAILS><RET_DETAIL><SN></SN><PAY_STATUS></PAY_STATUS><RET_CODE>0090</RET_CODE><ERR_MSG>原交易未找到</ERR_MSG></RET_DETAIL></RET_DETAILS></BODY></GZELINK>
------------------------------------------------------------------------------
<BODY><QUERY_TRANS><QUERY_SN>1711271010346380</QUERY_SN><QUERY_REMARK/></QUERY_TRANS><RET_DETAILS><RET_DETAIL><SN/><PAY_STATUS/><RET_CODE>0090</RET_CODE><ERR_MSG>原交易未找到</ERR_MSG></RET_DETAIL></RET_DETAILS></BODY>
------------------------------------------------------------------------------
<BODY><QUERY_TRANS><QUERY_SN>1711271010346380</QUERY_SN><QUERY_REMARK></QUERY_REMARK></QUERY_TRANS><RET_DETAILS><RET_DETAIL><SN></SN><PAY_STATUS></PAY_STATUS><RET_CODE>0090</RET_CODE><ERR_MSG>原交易未找到</ERR_MSG></RET_DETAIL></RET_DETAILS></BODY>
結果對比: