我有一个xm文件,我使用XSLT transformation
使用DOM解析它并将数据存储到csv中。
但是现在我想在SAX中这样做,因为xml文件非常大。
现在我的问题是我们可以使用SAX parser
进行xslt转换并将数据存储到csv中吗?
我到处搜索,但我没有任何有用的信息。
这是我用DOM编写的java代码
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 {
// Setting path for .xsl file
File stylesheet = new File("style.xsl");
// Setting path for Eurex xml feed file
File xmlSource = new File("eurex_ref_data.xml");
//Dom initialization and parse xml
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
// Transformation of parsed xml to csv
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
Source source = new DOMSource(document);
//System.out.println(source.toString());
System.out.println("Generating CSV File");
Result outputTarget = new StreamResult(new File("AID.csv"));
transformer.transform(source, outputTarget);
System.out.println("File has been generated");
}
}
这是我的示例XSLT代码..
<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"/>
<xsl:template match="/">
<xsl:text>PriSetPx,TxnTm,ID,AltID,AltIDSrc</xsl:text>
<xsl:text>
</xsl:text>
<xsl:for-each select="FIXML/Batch/SecDef">
<xsl:variable name="secDef" select="concat(@PriSetPx,',',@TxnTm)" />
<xsl:for-each select="Instrmt/AID">
<xsl:value-of select="concat($secDef, ',',../@ID,',',@AltID,',',@AltIDSrc,'
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
提前致谢!
答案 0 :(得分:1)
有SAXSource
https://docs.oracle.com/javase/8/docs/api/javax/xml/transform/sax/SAXSource.html和StreamSource
https://docs.oracle.com/javase/8/docs/api/javax/xml/transform/stream/StreamSource.html因此您根本不需要使用DOM来使用XSLT和Java。但您必须了解XSLT 1.0和2.0在任何情况下都会将完整的XML输入首先解析为建模XSLT / XPath数据模型的树表示。因此,虽然XSLT 1.0或2.0处理器的本机树模型可能比DOM树消耗更少的内存,但它肯定会随着输入的大小而增长。
至于您当前的代码,为避免明确使用DOM,您只需使用StreamSource
(或者如果您真的需要SAXSource
)而不是DOMSource
transformer.transform(source, outputTarget);
1}}。
所以请使用例如
File xmlSource = new File("eurex_ref_data.xml");
Source source = new StreamSource(xmlSource);
让XSLT处理器使用其原生树表示。
如果您想处理非常大的XML文档并遇到内存问题,那么您可能需要查看XSLT 3.0和streaming(目前Saxon 9 EE支持,http://saxonica.com/html/documentation/using-xsl/embedding/jaxp-transformation.html),例如您添加到问题中的样式表可以轻松编写为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:mode streamable="yes"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>PriSetPx,TxnTm,ID,AltID,AltIDSrc</xsl:text>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="FIXML/Batch/SecDef/Instrmt/AID"/>
</xsl:template>
<xsl:template match="AID">
<xsl:value-of select="ancestor::SecDef/@PriSetPx, ancestor::SecDef/@TxnTm, ../@ID, @AltID, @AltIDSrc" separator=","/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
然后很容易与Saxon 9.7或9.8 EE(http://saxonica.com/download/download_page.xml)一起使用和流式传输来创建CSV而不需要消耗太多内存,因为XSLT和流式传输避免了首先构建完整输入的树而是通过XML只能一次转发,逐个节点地处理它。
如果您有非常大的输入文档(我不确定他们支持XSLT有多好,他们专注于XQuery),或者考虑使用像BaseX或ExistDB这样的XML数据库。