2017-06-14 76 views
0

我想通過XSLT遞歸讀取以下xml屬性的數據。需要關於從xml中遞歸獲取數據的幫助

這是我的示例XML數據!

<FIXML ....."> 
    <Batch ....> 
    <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"> 
    . 
    . 
    . 
    </MktDef> 
    <MktDef MktID="XEUR" MktSegID="19629" EfctvBizDt="2017-05-11" NxtEfctvBizDt="2017-05-15" MktSeg="FBON" MarketSegmentDesc="EURO BONO FUTURE 8,5-10,5 YEAR" Sym="DE000A163W29" ParentMktSegmID="FBND" Ccy="EUR" MktSegStat="1" USFirmFlag="Y" PartID="2"> 
    . 
    . 
    . 
    </MktDef> 
    . 
    . 
    . 

這是我的XSLT

<?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="/"> 
MktID,MktSegID,EfctvBizDt,NxtEfctvBizDt,MktSeg,MarketSegmentDesc,Sym,ParentMktSegmID,Ccy,MktSegStat,USFirmFlag,PartID 
<xsl:for-each select="/"> 
<xsl:value-of select="concat(ancestor::FIXML/Batch/MktDef/@MktID,',',ancestor::FIXML/Batch/MktDef/@MktSegID,',',ancestor::FIXML/Batch/MktDef/@EfctvBizDt,',',ancestor::FIXML/Batch/MktDef/@NxtEfctvBizDt,',',ancestor::FIXML/Batch/MktDef/@MktSeg,',',ancestor::FIXML/Batch/MktDef/@MarketSegmentDesc,',',ancestor::FIXML/Batch/MktDef/@Sym,',',ancestor::FIXML/Batch/MktDef/@ParentMktSegmID,',',ancestor::FIXML/Batch/MktDef/@Ccy,',',ancestor::FIXML/Batch/MktDef/@MktSegStat,',',ancestor::FIXML/Batch/MktDef/@USFirmFlagt,',',ancestor::FIXML/Batch/MktDef/@PartID,'&#xA;')"/> 
</xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

這是我的Java代碼..

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("MktDef.csv")); 
     transformer.transform(source, outputTarget); 

    } 
} 

我解析此XML,並試圖獲取數據從MktDef屬性,並將其存儲CSV格式如下,

MktID MktSegID EfctvBizDt NxtEfctvBizDt MktSeg MarketSegmentDesc Sym ParentMktSegmID Ccy MktSegStat USFirmFlag PartID 
XEUR 14 5/11/2017 5/15/2017 CONF FUT 8-13 Y. SWISS GOV.BONDS 6% CH0002741988 FBND CHF 1  2 
XEUR 14 5/11/2017 5/15/2017 CONF FUT 8-13 Y. SWISS GOV.BONDS 6% CH0002741988 FBND CHF 1  2 
XEUR 14 5/11/2017 5/15/2017 CONF FUT 8-13 Y. SWISS GOV.BONDS 6% CH0002741988 FBND CHF 1  2 
XEUR 14 5/11/2017 5/15/2017 CONF FUT 8-13 Y. SWISS GOV.BONDS 6% CH0002741988 FBND CHF 1  2 
. 
. 
. 

我現在面臨的問題是我只能得到第一個MktDef數據。我瞭解XSLT中存在一些邏輯問題。

對於XML和XSLT的工作我很新,所以請大家幫助我解決這個問題。 在此先感謝!

+0

Java在所有這些方面在哪裏? –

+0

我剛剛添加了Java代碼。 –

回答

1

如果您位於根節點模板(/)的內部,則選擇for-each中的XPath與該節點相關。你想迭代每個MktDef元素,所以它應該是FIXML/Batch/MktDef

現在,在for-each中,上下文節點在每次迭代中變爲當前的MkDef元素。因此,要獲得當前MktDef元素的屬性值,你從中選擇相對的:即@MktSegID

另外,如果你是發射文字文本,喜歡你的CSV標題行,把它<xsl:text>元素裏面,這樣你可以在模板中使用文本格式和縮進,並且空白不被視爲重要。

<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,EfctvBizDt,NxtEfctvBizDt,MktSeg,MarketSegmentDesc,Sym,ParentMktSegmID,Ccy,MktSegStat,USFirmFlag,PartID&#xA;</xsl:text> 

    <xsl:for-each select="FIXML/Batch/MktDef"> 
     <xsl:value-of select="concat(@MktID,',',@MktSegID,',',@EfctvBizDt,',',@NxtEfctvBizDt,',',@MktSeg,',',@MarketSegmentDesc,',',@Sym,',',@ParentMktSegmID,',',@Ccy,',',@MktSegStat,',',@USFirmFlagt,',',@PartID,'&#xA;')"/> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
+0

嗨Hanse,謝謝你的幫助。我可以通過修改後的XSLT獲取所有數據,但存在一個小問題。獲取列名後,第一行數據即將出現在列名稱之外。 MktID,.... MktSegStat \t USFirmFlag \t Part ID \t XEUR 2017/5/11 \t 2017/5/15 \t CONF。如何在下一行獲取此行? –

+0

例如,我想在之後換行。所以我們從每個循環中提取的數據將進入下一行。你能幫忙嗎?謝謝! –

+0

哎呀!我遺漏了在標題行結尾的行的實體引用 –