使用java将XML文件转换为CSV文件
我需要帮助了解使用java将XML文件转换为CSV文件所涉及的步骤。 这是一个XML文件的例子
<?xml version="1.0"?> <Sites> <Site id="101" name="NY-01" location="New York"> <Hosts> <Host id="1001"> <Host_Name>srv001001</Host_Name> <IP_address>10.1.2.3</IP_address> <OS>Windows</OS> <Load_avg_1min>1.3</Load_avg_1min> <Load_avg_5min>2.5</Load_avg_5min> <Load_avg_15min>1.2</Load_avg_15min> </Host> <Host id="1002"> <Host_Name>srv001002</Host_Name> <IP_address>10.1.2.4</IP_address> <OS>Linux</OS> <Load_avg_1min>1.4</Load_avg_1min> <Load_avg_5min>2.5</Load_avg_5min> <Load_avg_15min>1.2</Load_avg_15min> </Host> <Host id="1003"> <Host_Name>srv001003</Host_Name> <IP_address>10.1.2.5</IP_address> <OS>Linux</OS> <Load_avg_1min>3.3</Load_avg_1min> <Load_avg_5min>1.6</Load_avg_5min> <Load_avg_15min>1.8</Load_avg_15min> </Host> <Host id="1004"> <Host_Name>srv001004</Host_Name> <IP_address>10.1.2.6</IP_address> <OS>Linux</OS> <Load_avg_1min>2.3</Load_avg_1min> <Load_avg_5min>4.5</Load_avg_5min> <Load_avg_15min>4.2</Load_avg_15min> </Host> </Hosts> </Site> </Sites>
这里是结果的CSV文件。
site_id, site_name, site_location, host_id, host_name, ip_address, operative_system, load_avg_1min, load_avg_5min, load_avg_15min 101, NY-01, New York, 1001, srv001001, 10.1.2.3, Windows, 1.3, 2.5, 1.2 101, NY-01, New York, 1002, srv001002, 10.1.2.4, Linux, 1.4, 2.5, 1.2 101, NY-01, New York, 1003, srv001003, 10.1.2.5, Linux, 3.3, 1.6, 1.8 101, NY-01, New York, 1004, srv001004, 10.1.2.6, Linux, 2.3, 4.5, 4.2
我正在考虑使用DOMparsing器来读取XML文件。 我遇到的问题是我需要指定特定的元素来按名称编码,但是我希望它能够parsing它而不这样做。
在java中有任何工具或库,可以帮助我实现这一点。
如果我有下面这种格式的XML文件,并且希望在MSgId的同一行添加InitgPty的值(请注意:InitgPty位于下一个标记级别,因此它将在下一行中打印该值)
<?xml version="1.0"?> <CstmrCdtTrfInitn> <GrpHdr> <MsgId>XYZ07/ABC</MsgId> <NbOfTxs>100000</NbOfTxs> <InitgPty> <Nm>XYZ</Nm> </InitgPty>
这里有一个工作的例子, data.xml
有你的数据:
import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; class Xml2Csv { public static void main(String args[]) throws Exception { File stylesheet = new File("src/main/resources/style.xsl"); File xmlSource = new File("src/main/resources/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); Result outputTarget = new StreamResult(new File("/tmp/x.csv")); transformer.transform(source, outputTarget); } }
style.xsl
<?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="/"> Host_Name,IP_address,OS,Load_avg_1min,Load_avg_5min,Load_avg_15min <xsl:for-each select="//Host"> <xsl:value-of select="concat(Host_Name,',',IP_address,',',OS,Load_avg_1min,',',Load_avg_5min,',',Load_avg_15min,'
')"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
输出:
Host_Name,IP_address,OS,Load_avg_1min,Load_avg_5min,Load_avg_15min srv001001,10.1.2.3,Windows1.3,2.5,1.2 srv001002,10.1.2.4,Linux1.4,2.5,1.2 srv001003,10.1.2.5,Linux3.3,1.6,1.8 srv001004,10.1.2.6,Linux2.3,4.5,4.2
三步:
- 将XML文件parsing为一个java XML库对象。
- 从每个行的对象中检索相关数据 。
- 使用本机java函数将结果写入文本文件 ,并以* .csv扩展名保存。
最好的办法是使用XSLT将XML“转换”为CSV。 有这样的Q / A(如这里 ),涵盖如何做到这一点。 关键是为您的源数据提供模式,以便XSLT转换过程知道如何读取它,以便正确格式化结果。
然后,您可以使用XalaninputXML,读取XSLT并输出结果。
一月份,Pedantic已经提供了答案(使用类似于DOM的方法{文档对象模型})和Jono(与这次类似SAX的方法)。
我的意见是,这两种方法适用于小文件,但后者更适合大XML文件。 你没有提到你的XML文件的实际大小,但你应该考虑到这一点。
无论使用什么方法,一个特定的程序(这将检测为您的本地XML定制的特殊标签)将更容易编写,但没有代码适应另一个XML风格,将无法正常工作,而更通用的程序将更难devise,但将工作对于所有的XML文件。 你说你想能够parsing一个文件而不指定特定的元素名称,所以我猜一般的方法是你喜欢的,我同意这一点,但请注意,说起来容易做起来难。 事实上,同样的问题也出现在一月份,暗示这次是一个很大的XML文件(>> 100Mo),而且我很惊讶到目前为止互联网上没有任何东西可用。 把挫折变成更好的东西总是一件好事,所以我决定用自己最普通的方式来处理这个特定的问题,特别是关于大XML文件问题 。
您可能有兴趣知道我编写的通用Java库(现在是以自由软件的forms发布)将您的XML文件转换为CSV文件(使用-x -u模式{请参阅文档获取更多信息}) 。
所以你的问题的最后一部分的答案是:是的,至less有一个库将帮助你实现你的目标,我的名字是“XML2CSV-Generic-Converter”。 当然也可能有其他的,当然也有更好的,但是我自己也不能挑一个像样的(免费的)。
我不会在这里提供任何链接来遵守Peter Foti的明智之言 – 但是如果您在您最喜爱的search引擎中键入“XML2CSV-Generic-Converter”,您应该可以轻松find它。
你的文件看起来非常平坦和简单。 您不一定需要XMLparsing器来转换它。 只需使用LineNumberReader.readLine()
parsing并使用正则regexp
来提取特定的字段。
另一个select是使用StAX
,一个用于XML处理的stream媒体API。 这很简单,你不需要加载整个文件在RAM中。