[英]How to print the recursive XML data into CSV file using XSLT
This is my sample XML data having only attributes data and having multiple child nodes,这是我的示例 XML 数据,只有属性数据和多个子节点,
<FIXML s="...." v="....">
<Batch ID="....">
<MktDef MktID="XEUR" MktSegID="14" EfctvBizDt="2017-05-11" NxtEfctvBizDt="2017-05-15" MktSeg="CONF" MarketSegmentDesc="FUT 8-13 Y. SWISS GOV.BONDS 6%" Sym="CH0002741988" ParentMktSegmID="FBND" Ccy="CHF" MktSegStat="1" USFirmFlag="Y" PartID="2">
<MtchRules MtchRuleProdCmplx="5" MtchAlgo="PT"/>
<MtchRules MtchRuleProdCmplx="1" MtchAlgo="PT"/>
<FlexProdEligs FlexProdEligCmplx="5" FlexProdElig="Y"/>
<BaseTrdgRules QtSideInd="1" FastMktPctg="0">
<TickRules TickRuleProdCmplx="1" StartTickPxRng="0" EndTickPxRng="99999.9999" TickIncr="0.01"/>
<TickRules TickRuleProdCmplx="5" StartTickPxRng="0" EndTickPxRng="99999.9999" TickIncr="0.01"/>
<QuotSizeRules MinBidSz="1" MinOfrSz="1" FastMktInd="0"/>
<QuotSizeRules MinBidSz="1" MinOfrSz="1" FastMktInd="1"/>
<PxRngRules PxRngRuleID="75" PxRngProdCmplx="1" StartPxRng="0" EndPxRng="99999.9999" PxRngValu="0.15"/>
<PxRngRules PxRngRuleID="347" PxRngProdCmplx="5" StartPxRng="0" EndPxRng="99999.9999" PxRngValu="0.12"/>
</BaseTrdgRules>
<MDFeedTyps MDFeedTyp="HS" MDBkTyp="2" MktDepth="10" MDRcvryTmIntvl="120000" SvcLctnID1="224.0.50.102" SvcLctnSubID1="59500" SvcLctnID2="224.0.50.230" SvcLctnSubID2="59500"/>
<MDFeedTyps MDFeedTyp="HI" MDBkTyp="2" MktDepth="10" MktDepthTmIntvl="0" SvcLctnID1="224.0.50.103" SvcLctnSubID1="59501" SvcLctnID2="224.0.50.231" SvcLctnSubID2="59501"/>
<MDFeedTyps MDFeedTyp="HI" MDBkTyp="3" MktDepthTmIntvl="0" SvcLctnID1="224.0.114.97" SvcLctnSubID1="59501" SvcLctnID2="224.0.114.113" SvcLctnSubID2="59501"/>
<MDFeedTyps MDFeedTyp="HS" MDBkTyp="3" SvcLctnID1="224.0.114.96" SvcLctnSubID1="59500" SvcLctnID2="224.0.114.112" SvcLctnSubID2="59500"/>
<MDFeedTyps MDFeedTyp="L" MDBkTyp="2" MktDepth="5" MktDepthTmIntvl="3500" MDRcvryTmIntvl="30000" SvcLctnID1="224.0.50.89" SvcLctnSubID1="59500" SvcLctnID2="224.0.50.217" SvcLctnSubID2="59500"/>
</MktDef>
<SecDef PriSetPx="158.39">
<Instrmt ID="408805" Src="M" SecTyp="FUT" Status="1" ProdCmplx="1" CFI="FFMPSX" MatDt="2017-06-08" MMY="201706" Mult="1" ValMeth="FUT" SettlMeth="P" SettlSubMeth="4" PxPrcsn="2" MinPxIncr="0.01" MinPxIncrAmt="10">
<AID AltID="1048612" AltIDSrc="M"/>
<AID AltID="XF000001RQD8" AltIDSrc="4"/>
<Evnt EventTyp="7" Dt="2017-06-08"/>
</Instrmt>
<MktSegGrp MktSegID="14">
<SecTrdgRules>
<BaseTrdgRules>
<PxRngRules PxRngRuleID="75"/>
</BaseTrdgRules>
</SecTrdgRules>
</MktSegGrp>
</SecDef>
.
.
.
.
</Batch>
</FIXML>
"<MktDef> and <SecDef>" will be continued for N number of times.
Sample XSLT file:示例 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" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:text>MktID,MktSegID,PxRngRuleID,PxRngProdCmplx,StartPxRng,EndPxRng,PxRngValu,</xsl:text>
<xsl:for-each select="FIXML/Batch/MktDef">
<xsl:value-of select="concat(@MktID,',',@MktSegID,',',ancestor::FIXML/Batch/MktDef/BaseTrdgRules/PxRngRules/@PxRngRuleID,',',@PxRngProdCmplx,',',@StartPxRng,',',@EndPxRng,',',@PxRngValu,'
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Java code to convert XML data to csv:将 XML 数据转换为 csv 的 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 {
File stylesheet = new File("style.xsl");
//File xmlSource = new File("Testing-1.xml");
File xmlSource = new File("95FILRDF01PUBLI20170511XEUR6NJ92000.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);
System.out.println(source.toString());
System.out.println("Hello");
Result outputTarget = new StreamResult(new File("PxRngRules.csv"));
transformer.transform(source, outputTarget);
}
}
Here I want to get the output in the format below.在这里,我想以下面的格式获取输出。
MktID MktSegID PxRngRuleID PxRngProdCmplx StartPxRng EndPxRng PxRngValu
XEUR 19629 75 1 0 99999.9999 0.15
XEUR 65 75 1 0 99999.9999 0.15
XEUR 66 75 1 0 99999.9999 0.15
XEUR 67 75 1 0 99999.9999 0.15
The problem I is I am only getting first "PxRngRules" tag data.我的问题是我只得到第一个“PxRngRules”标签数据。 I am unable to get the all the occurrences of "PxRngRules".我无法获得所有出现的“PxRngRules”。
I may have misunderstood your requirement, but you could try this XSLT, if you wanted multiple lines for each PxRngRules
under a MktDef
我可能误解了你的要求,但你可以试试这个XSLT,如果你想多行每个PxRngRules
下MktDef
<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>MktID,MktSegID,PxRngRuleID,PxRngProdCmplx,StartPxRng,EndPxRng,PxRngValu</xsl:text>
<xsl:text>
</xsl:text>
<xsl:for-each select="FIXML/Batch/MktDef">
<xsl:variable name="mktDef" select="concat(@MktID,',',@MktSegID)" />
<xsl:choose>
<xsl:when test="BaseTrdgRules/PxRngRules">
<xsl:for-each select="BaseTrdgRules/PxRngRules">
<xsl:value-of select="concat($mktDef, ',', @PxRngRuleID,',',@PxRngProdCmplx,',',@StartPxRng,',',@EndPxRng,',',@PxRngValu,'
')"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($mktDef, ',,,,,
')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
If there was always going to be at least one PxRngRules
for each MktDef
(or if you didn't want output MktDef
elements with no PxRngRules
you could simplify the code to this如果每个MktDef
总是至少有一个PxRngRules
(或者如果您不想输出没有PxRngRules
MktDef
元素,您可以将代码简化为
<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>MktID,MktSegID,PxRngRuleID,PxRngProdCmplx,StartPxRng,EndPxRng,PxRngValu</xsl:text>
<xsl:text>
</xsl:text>
<xsl:for-each select="FIXML/Batch/MktDef">
<xsl:variable name="mktDef" select="concat(@MktID,',',@MktSegID)" />
<xsl:for-each select="BaseTrdgRules/PxRngRules">
<xsl:value-of select="concat($mktDef, ',', @PxRngRuleID,',',@PxRngProdCmplx,',',@StartPxRng,',',@EndPxRng,',',@PxRngValu,'
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.