Convert XML having multiple for-each case to CSV

 

问题

https://stackoverflow.com/questions/68605295/convert-xml-having-multiple-for-each-case-to-csv

I have written a Java Program that converts XML to CSV. But currently it is converting partial only.

FileUtils.writeByteArrayToFile(new File("src/main/resources/excel/Data.xml"), inputFile);

File stylesheet = new File("src/main/resources/excel/Data.xsl");

File xmlSource = new File("src/main/resources/excel/Data.xml");

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

Document document = builder.parse(xmlSource);

StreamSource stylesource = new StreamSource(stylesheet);

Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);

Source source = new DOMSource(document);

String path = "src/main/resources/excel/validatedXmlToCSV.csv";

Result outputTarget = new StreamResult(new File(path));

transformer.transform(source, outputTarget);

This is the Java code that takes XML and XSL and converts it to the CSV.

XML file that I am trying to convert it to CSV is:

<root>

<row>

<TECHNICIANID>AA5263</TECHNICIANID>

<CUID>AA5263</CUID>

<TURFS>

<TURF>

<AREANAME>CA_MILPITAS_ABEL_A</AREANAME>

<DEFAULT>Y</DEFAULT>

<ALTERNATE>Y</ALTERNATE>

</TURF>

<TURF>

<AREANAME>CA_SNJS_WHITE_RD_A</AREANAME>

<DEFAULT>Y</DEFAULT>

<ALTERNATE>Y</ALTERNATE>

</TURF>

</TURFS>

</row>

<row>

<TECHNICIANID>AC1964</TECHNICIANID>

<CUID>AC1964</CUID>

<TURFS>

<TURF>

<AREANAME>CA_MILPITAS_ABEL_A</AREANAME>

<DEFAULT>Y</DEFAULT>

<ALTERNATE>Y</ALTERNATE>

</TURF>

<TURF>

<AREANAME>CA_SNJS_WHITE_RD_A</AREANAME>

<DEFAULT>Y</DEFAULT>

<ALTERNATE>Y</ALTERNATE>

</TURF>

</TURFS>

</row>

</root>

Let me show you how I wrote XSL file that it not working properly:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:fo="http://www.w3.org/1999/XSL/Format" >

<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>

<xsl:template match="/">TECHNICIANID,CUID,TURFS/TURF/0/AREANAME,TURFS/TURF/0/DEFAULT,TURFS/TURF/0/ALTERNATE,TURFS/TURF/1/AREANAME,TURFS/TURF/1/DEFAULT,TURFS/TURF/1/ALTERNATE

<xsl:for-each select="/root/row">

<xsl:value-of select="concat(TECHNICIANID,',',CUID,'

&#xA;')"/>

<xsl:for-each select="/TURFS/TURF">

<xsl:value-of select="concat(AREANAME,',',DEAFAULT,',',ALTERNATE,',

&#xA;')"/>

</xsl:for-each>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

Currently while converting it is printing row TECHNICIANID and CUID only. Other it is not printing.

Expected Output:

TECHNICIANID,CUID,TURFS/TURF/0/AREANAME,TURFS/TURF/0/DEFAULT,TURFS/TURF/0/ALTERNATE,TURFS/TURF/1/AREANAME,TURFS/TURF/1/DEFAULT,TURFS/TURF/1/ALTERNATE

AA5263,AA5263,CA_MILPITAS_ABEL_A,Y,Y,CA_SNJS_WHITE_RD_A,Y,Y

AC1964,AC1964,CA_MILPITAS_ABEL_A,Y,Y,CA_SNJS_WHITE_RD_A,Y,Y

解答

这个问题需要从包含多级父子节点的xml中提取数据导出csv文件Java 实现则代码较长。

Java 下的开源包 SPL 很容易写,只要几句:


A

1

=xml(file("Data.xml").read(),"root/row").conj(TECHNICIANID|CUID|TURFS.TURF.conj(~.array()))

2

=create(TECHNICIANID,CUID,TURFS/TURF/0/AREANAME,TURFS/TURF/0/DEFAULT,TURFS/TURF/0/ALTERNATE,TURFS/TURF/1/AREANAME,TURFS/TURF/1/DEFAULT,TURFS/TURF/1/ALTERNATE).record(A1)

3

=file("validatedXmlToCSV.csv").export@ct(A2)

SPL提供了JDBC 供 JAVA 调用,把上面的脚本存为 xml2csv.splx,在 JAVA 中以存储过程的方式调用脚本文件:

Class.forName("com.esproc.jdbc.InternalDriver");

con= DriverManager.getConnection("jdbc:esproc:local://");

st=con.prepareCall("call xml2csv()");

st.execute();

SPL 源代码:https://github.com/SPLWare/esProc

问答搜集