dom4j解析xml重复节点
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dom4j解析xml重复节点相关的知识,希望对你有一定的参考价值。
xml如下
<?xml version="1.0" encoding="UTF-8"?>
<PACKET type="RESPONSE" version="1.0">
<BODY>
<EDOR_LIST>
<EDOR>
<EDORNO></EDORNO>
<EDORVALIDATE></EDORVALIDATE>
<EDORTYPE></EDORTYPE>
</EDOR>
<EDOR>
<EDORNO></EDORNO>
<EDORVALIDATE></EDORVALIDATE>
<EDORTYPE></EDORTYPE>
</EDOR>
……<!—多条循环 -->
</EDOR_LIST>
</BODY>
</PACKET>
如何拿到EDOR_LIST节点下每一个EDOR节点,解析EDOR节点下的所有值
我做到这一步,不知道下一步怎么做了
已经解析出来了,代码如下:
List<Element> backList = doc.selectNodes("/PACKET/BODY/EDOR_LIST");
for(int i=0 ; i<backList.size();i++)
Element backListEle= backList.get(i);
String edorNo=convertNull(backListEle.selectSingleNode("EDORNO").getText());
String edorDate=convertNull(backListEle.selectSingleNode("EDORVALIDATE").getText());
String edorType=convertNull(backListEle.selectSingleNode("EDORTYPE").getText());
解析出来了,该怎么用怎么用,下面那个回答简直无技术含量(从别的贴吧抄的,我看过无数次!故不予采纳!)
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class XmlTest2
public static void main(String[] args)
SAXReader reader = new SAXReader();
reader.setEncoding("UTF-8");
Document doc = null;
try
File file = new File("test2.xml");
doc = reader.read(file);
printNode(doc.selectNodes("DSExport/Job"));
catch (DocumentException e)
e.printStackTrace();
public static void printNode(List<Node> nodeList)
for (Node jobNode : nodeList)
printProperty(jobNode.selectNodes("Record/Property"));
printProperty(jobNode.selectNodes("Record/Collection/SubRecord/Property"));
public static void printProperty(List<Node> propertyNodeList)
for (Node propertyNode : propertyNodeList)
System.out.println(propertyNode.getUniquePath() + ">>" + propertyNode.selectSingleNode("@Name").getText() + ":" + propertyNode.getText());
SQL XML解析不同节点
【中文标题】SQL XML解析不同节点【英文标题】:SQL XML parsing different nodes 【发布时间】:2019-10-24 15:35:02 【问题描述】:我想请你帮忙解析 SQL 中的 XML,我的 XML 看起来像这样,其中 Load 是可以重复 X 次的父项。我需要 Column SerNr 并且每一行都需要绑定订单名称 决赛桌看起来像这样
表格示例:
<ImageHistory>
<Load targets="2" totalTime="417">
<Orders>
<Order name="20548976"/>
</Orders>
<Data>
<Disk SerNr="XXXXXX" Size_mb="228936" LoadSuccessfull="true" />
<Disk SerNr="ZZZZZ" Size_mb="228936" LoadSuccessfull="true" />
</Data>
</Load>
</ImageHistory>
sql是
with data as (SELECT CAST(MY_XML AS xml) as MY_XML FROM OPENROWSET(BULK 'addres to xml', SINGLE_BLOB) AS T(MY_XML)),
datainfo as (
SELECT
MY_XML.Blasting.value(' @name', 'BIGINT') as Size_mb,
MY_XML.Blasting.value('@SerNr', 'varchar(32)') as SerNr
FROM data CROSS APPLY MY_XML.nodes('ImageHistory/Load/Data/Disk') AS MY_XML (Blasting))
select * from datainfo
谢谢你的帮助
【问题讨论】:
【参考方案1】:我将 XML 保存为文件系统上的文件:e:\Temp\DiskSerialNumbers.xml 其余的在下面。
SQL
;WITH XmlFile (Contents) AS
(
SELECT CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK 'e:\Temp\DiskSerialNumbers.xml', SINGLE_BLOB) AS XmlData
)
SELECT c.value('(../../Orders/Order/@name)[1]', 'INT') AS [Name]
, c.value('@SerNr', 'VARCHAR(20)') AS [SerNr]
FROM XmlFile CROSS APPLY Contents.nodes('/ImageHistory/Load/Data/Disk') AS t(c);
输出
+----------+--------+
| Name | SerNr |
+----------+--------+
| 20548976 | XXXXXX |
| 20548976 | ZZZZZ |
+----------+--------+
【讨论】:
嗨 Yitzhak,我刚刚添加了一个替代方案,因为向后导航是性能杀手... 嗨,Shnugo,很划算。我非常清楚向后 XPath 导航是性能杀手。提供的 XML 示例非常小,所以我没有费心使用两个 CROSS APPLY 子句...【参考方案2】:你已经有了答案,但我想指出一个事实,向后导航(使用../../
)是horribly slow with bigger structures。
我建议这样做:
模拟您的问题的模型:
DECLARE @yourTable TABLE(ID INT IDENTITY,YourXml XML);
INSERT INTO @yourTable VALUES
(N'<ImageHistory>
<Load targets="2" totalTime="417">
<Orders>
<Order name="20548976" />
</Orders>
<Data>
<Disk SerNr="XXXXXX" Size_mb="228936" LoadSuccessfull="true" />
<Disk SerNr="ZZZZZ" Size_mb="228936" LoadSuccessfull="true" />
</Data>
</Load>
</ImageHistory>');
--查询
SELECT t.ID
,ld.value('@targets','int') AS Load_Targets
,ld.value('@totalTime','int') AS Load_TotalTime
,ld.value('(Orders/Order/@name)[1]','int') AS Order_Name
,dsk.value('@SerNr','nvarchar(100)') AS Disk_SerNr
,dsk.value('@Size_mb','nvarchar(100)') AS Disk_Size_mb
,dsk.value('@LoadSuccessfull','bit') AS Disk_LoadSuccessfull
FROM @yourTable AS t
CROSS APPLY t.YourXml.nodes('/ImageHistory/Load') A(ld)
CROSS APPLY A.ld.nodes('Data/Disk') B(dsk);
简而言之:
第一个APPLY
将下潜到<Load>
并将返回所有<Load>
元素(如果还有更多...
第二个APPLY
将使用第一个APPLY
返回的片段并深入到<Disk>
。
我们针对第一个片段(即<Load>
元素)调用.value()
获取订单名称(和其他值),并针对第二个@ 的片段调用.value()
获取<Disk>
的值987654335@。
【讨论】:
以上是关于dom4j解析xml重复节点的主要内容,如果未能解决你的问题,请参考以下文章