Dom4j的selectNodes处出错解决办法

本文通过一个小例子展示了如何使用dom4j解析XML文件,包括加载文档、选择节点和提取属性值的过程。
来自:http://apps.hi.baidu.com/share/detail/31234917
Element root = document.getRootElement();

List recordenvlist = document.selectNodes("//gml:envelope"); //gml:envelope

提示
NoClassDefFoundError
org.dom4j.DocumentFactory.createXPath
原因:dom4j的xpath api依赖jaxen完成
解决方法:在系统中加入jaxen.jar.
jaxen.jar下载路径:http://jaxen.codehaus.org/releases.html
dom4j-1.6.1.jar下载路
http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.jar

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

使用dom4j的xPath解析XML


国外的dom4j已经很流行了,国内的相关资料相对较少,但普及风暴也即将到来。我们公司(老外开的)解析XML就是用的dom4j。
今天公司没事做,自己也写一个小例子贴上来,嘻~~

books.xml:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<!--This is a test for dom4j, jakoes, 2007.7.19-->
<book show="yes" url="lucene.net">
<title id="456">Lucene Studing</title>
</book>
<book show="yes" url="dom4j.com">
<title id="123">Dom4j Tutorials</title>
</book>
<book show="no" url="spring.org">
<title id="789">Spring in Action</title>
</book>
<owner>O'Reilly</owner>
</books>

下面我们使用dom4j的xPath来解析:

segment of ParseXML.java:

public void parseBooks(){

SAXReader reader = new SAXReader();
try {
Document doc = reader.read("books.xml");
Node root = doc.selectSingleNode("/books");
List list = root.selectNodes("book[@url='dom4j.com']");

for(Object o:list){

Element e = (Element) o;
String show=e.attributeValue("show");
System.out.println("show = " + show);
}

} catch (Exception e) {
e.printStackTrace();
}
}

Document doc = reader.read("books.xml");的意思是加载XML文档,此是可以用doc.asXML()来查看,它将打印整个xml文档。

Node root = doc.selectSingleNode("/books");是读取刚才加载的xml文档内的books节点下的所有内容,对于本例也是整个xml文档。
当然我们也可以加载/books下的某一个节点,如:book节点
Node root = doc.selectSingleNode("/books/book");
或:Node root = doc.selectSingleNode("/books/*");
注意:如果有多个book节点,它只会读取第一个
root.asXML()将打印:
<book show="yes" url="lucene.net">
<title id="456">Lucene Studing</title>
</book>

既然加载了这么多,那我怎么精确的得到我想要的节点呢,别急,看下面:
List list = root.selectNodes("book[@url='dom4j.com']");
它的意思就是读取books节点下的book节点,且book的节点的url属性为dom4j.com
为什么使用list来接收呢,如果有两个book节点,且它们的url属性都为dom4j.com,此时就封闭到list里了。

如果想读取books下的所有book节点,可以这样:
List list = root.selectNodes("book");

如果想读取books节点下的book节点下的title节点,可以这样:
List list2 = root.selectNodes("book[@url='dom4j.com']/title[@id='123']");

注意:selectNodes()参数的格式:
节点名[@属性名='属性值'],如:book[@url='dom4j.com']
如果有多个节点,用“/”分开,如:book[@url='dom4j.com']/title[@id='123']

最近就是读取封闭在List里的内容了,可以用Node来读取,也可以用Element来转换。
attributeValue("属性")是读取该节点的属性值
getText()是读取节点的的内容。
import org.dom4j.*; import org.dom4j.io.SAXReader; import java.io.ByteArrayInputStream; import java.io.StringReader; import java.util.List; public class cs3 { public static void main(String[] args) { String s1 = "<inputMsgBody> <ReportRequestTable> <ReportRequestObject> <MedReportNo>20251121G0030001</MedReportNo> <ItemNames>钾</ItemNames> <RequestDoctorId>00</RequestDoctorId> <RequestDoctor>超级管理</RequestDoctor> <RequestDate>20-11月-25</RequestDate> <RequestDeptId></RequestDeptId> <RequestDept>10010301</RequestDept> <RequestWardId>100514</RequestWardId> <RequestWard>测试病区</RequestWard> <RequestBedId>06床</RequestBedId> <RequestBed>06床</RequestBed> <ReceiveDate>21-11月-25</ReceiveDate> <ReceiveStaffId>1001</ReceiveStaffId> <ReceiveStaffName>ceshi</ReceiveStaffName> </ReportRequestObject> </ReportRequestTable> <ReportHeadTable> <ReportHeadObject> <MedReportNo>20251121G0030001</MedReportNo> <HosptailId></HosptailId> <HisPatId></HisPatId> <HisVisitNo>60000004</HisVisitNo> <SysFlag>1</SysFlag> <BarCode>2511000004</BarCode> <ExecDeptId></ExecDeptId> <ExecDeptName></ExecDeptName> <ExamDoctorId>xh</ExamDoctorId> <ExamDoctorName>ceshi</ExamDoctorName> <ExamDate>21-11月-25</ExamDate> <ReportDoctorId>630925</ReportDoctorId> <ReportDoctorName>李倩如</ReportDoctorName> <ReportDate>2025-11-14 12:42:47</ReportDate> <Description></Description> <PublicDate>2025-11-14 12:42:47</PublicDate> <AuditDate>2025-11-14 12:42:47</AuditDate> <AuditStaffId>323022</AuditStaffId> <AuditStaffName>阮淑琳</AuditStaffName> <CriticalFlag>1</CriticalFlag> <ReportTypeFlag>0</ReportTypeFlag> <SampleKindId></SampleKindId> <SampleKind>静脉血清</SampleKind> <ReportKindId>29</ReportKindId> <ReportKind>生化组</ReportKind> <ReportDeptId>100304</ReportDeptId> <ReportDeptName>检验科</ReportDeptName> </ReportHeadObject> </ReportHeadTable> <ReportDetailTable> <ReportDetailObject> <LabResultNo>032C7859E8824CA3B5948374B720D4E7</LabResultNo> <MedReportNo>20251121G0030001</MedReportNo> <ItemId>0119</ItemId> <ItemName>钾离子测定</ItemName> <RelevantLabTest>2.00</RelevantLabTest> <ItemUnit>mmol/L</ItemUnit> <ItemMax></ItemMax> <ItemMin></ItemMin> <BandRange></BandRange> <ItemStatus>2</ItemStatus> <CriticalMinBand></CriticalMinBand> <CriticalMaxBand></CriticalMaxBand> <CriticalFlag>1</CriticalFlag> <ItemExamMethod></ItemExamMethod> <RelatedItemCode></RelatedItemCode> <Quantity>1</Quantity> <ItemIndex>1</ItemIndex> <ExamItemId></ExamItemId> <ItemExamValue></ItemExamValue> </ReportDetailObject> </ReportDetailTable> <AllergyResultTable> <AllergyResultObject/> </AllergyResultTable> <BacteriaResultTable> <BacteriaResultObject/> </BacteriaResultTable></inputMsgBody>"; try { // 转换为dom4j的Element对象 //Element rootElement = convertToDom4jElement(s1); //解析报文 SAXReader srcReader = new SAXReader(); Document doc = null; doc = srcReader.read(new ByteArrayInputStream(s1.getBytes("UTF-8"))); Element rootElement = doc.getRootElement(); System.out.println(rootElement.asXML()); //获取报告申请信息 List<Node> list = rootElement.selectNodes("/ReportRequestTable"); System.out.println(list.toString()); Element requestNode = (Element)rootElement.selectSingleNode("/ReportRequestTable/ReportRequestObject"); System.out.println(requestNode.asXML()); Element medReportNo = requestNode.element("MedReportNo"); String report_no = medReportNo.getText(); String apply_dr_id = requestNode.elementText("RequestDoctorId"); String apply_dr_name = requestNode.elementText("RequestDoctor"); String apply_dept_code = requestNode.elementText("RequestDeptId"); String apply_dept_name = requestNode.elementText("RequestDept"); String pat_ward_id = requestNode.elementText("RequestWardId"); String pat_ward = requestNode.elementText("RequestWard"); String bed_no = requestNode.elementText("RequestBed"); //获取报告主体信息 Element headNode = (Element)rootElement.selectSingleNode("/ReportHeadTable/ReportHeadObject"); String patient_id = headNode.elementText("HisPatId"); String source = requestNode.elementText("SysFlag"); String inhosp_no = ""; String outhosp_no = ""; switch(source){ case"1": source = "1"; outhosp_no = headNode.elementText("HisVisitNo"); break;//门诊 case"2": source = "3"; inhosp_no = headNode.elementText("HisVisitNo"); break;//住院 case"3": source = "4"; outhosp_no = headNode.elementText("HisVisitNo"); inhosp_no = headNode.elementText("HisVisitNo"); break;//体检 default: outhosp_no = headNode.elementText("HisVisitNo"); inhosp_no = headNode.elementText("HisVisitNo"); } String exam_dept_code = headNode.elementText("ExecDeptId"); String exam_dept_name = headNode.elementText("ExecDeptName"); String exam_dr_code = headNode.elementText("ExamDoctorId"); String exam_dr_name = headNode.elementText("ExamDoctorName"); String report_time = headNode.elementText("PublicDate"); String report_check_time = headNode.elementText("AuditDate"); String report_check_dr_code = headNode.elementText("AuditStaffId"); String report_check_dr_name = headNode.elementText("AuditStaffName"); String test_categ_code = headNode.elementText("ReportTypeFlag"); String test_categ_name = ""; switch (test_categ_code){ case "0": test_categ_name = "常规检验";break; case "1": test_categ_name = "药敏";break; case "2": test_categ_name = "微生物";break; case "3": test_categ_name = "其他";break; } String specimenCode = headNode.elementText("SampleKindId"); String specimenName = headNode.elementText("SampleKind"); String report_dept_code = headNode.elementText("ReportDeptId"); String report_dept_name = headNode.elementText("ReportDeptName"); //获取项目信息 List<Node> detailNode = rootElement.selectNodes("/ReportDetailTable/ReportDetailObject"); String test_item_code = ""; String test_item_name = ""; String test_result_value = ""; String test_result_value_unit = ""; String reference_ranges = ""; String normal_flag = "";//需计算 String dangerFlag = ""; String itemSql = ""; for(Node node : detailNode) { Element e = (Element) node; test_item_code = requestNode.elementText("ItemId"); test_item_name = requestNode.elementText("ItemName"); test_result_value = requestNode.elementText("ItemUnit"); test_result_value_unit = requestNode.elementText("ReportDeptName"); reference_ranges = requestNode.elementText("BandRange"); dangerFlag = requestNode.elementText("CriticalFlag"); normal_flag = requestNode.elementText("CriticalFlag"); itemSql = "insert into test_item(report_no,test_item_code,test_item_name,test_result_value,test_result_value_unit,reference_ranges,dangerFlag,normal_flag) " + " values('%','%','%','%','%','%','%','%')"; itemSql = String.format(itemSql, report_no,test_item_code,test_item_name, test_result_value,test_result_value_unit,reference_ranges, dangerFlag,normal_flag ); //执行sql System.out.println("itemSql:"+itemSql); } String reportSql = "insert into critical(" + "report_no,patient_id,apply_dr_id,apply_dr_name,apply_dept_code,apply_dept_name, " + "pat_ward_id,pat_ward,bed_no,inhosp_no,outhosp_no,source," + "exam_dept_code,exam_dept_name,exam_dr_code,exam_dr_name," + "report_time,report_check_time,report_check_dr_code,report_check_dr_name," + "test_categ_code,test_categ_name,specimenCode,specimenName," + "report_dept_code,report_dept_name " + ")"; reportSql = String.format(reportSql, report_no,patient_id,apply_dr_id,apply_dr_name,apply_dept_code,apply_dept_name, pat_ward_id,pat_ward,bed_no,inhosp_no,outhosp_no,source, exam_dept_code,exam_dept_name,exam_dr_code,exam_dr_name, report_time,report_check_time,report_check_dr_code,report_check_dr_name, test_categ_code,test_categ_name,specimenCode,specimenName, report_dept_code,report_dept_name ); //执行sql System.out.println("reportSql:"+reportSql); } catch (Exception e) { System.err.println("XML解析错误: " + e.getMessage()); e.printStackTrace(); } } /** * 提取CDATA内容的方法 * * @param cdataString 包含CDATA的字符串 * @return CDATA内的XML内容 * @throws DocumentException 如果XML解析失败 */ public static String extractCDataContent(String cdataString) throws DocumentException { // 包装CDATA字符串为有效的XML文档 String wrappedXml = "<wrapper>" + cdataString + "</wrapper>"; // 使用SAXReader解析XML SAXReader reader = new SAXReader(); Document document = reader.read(new StringReader(wrappedXml)); // 获取包装元素的文本内容(即CDATA内容) return document.getRootElement().getText(); } /** * 将XML字符串转换为dom4j的Element对象 * * @param xmlString 格式良好的XML字符串 * @return XML的根元素 * @throws DocumentException 如果XML解析失败 */ public static Element convertToDom4jElement(String xmlString) throws DocumentException { // 使用DocumentHelper解析XML字符串 Document document = DocumentHelper.parseText(xmlString); return document.getRootElement(); } } 运行后报错:XML解析错误: null java.lang.NullPointerException at cs3.main(cs3.java:28)
最新发布
12-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值