2012-10-08 265 views
1

我需要將XML傳遞給第三方系統,第三方可以理解並解析它。xml到xml轉換使用xslt

下面是我的輸入XML,我通過從數據庫中提取創建數據。

<FIXML> 
    <Header> 
     <RequestID>ReqID8942</RequestID> 
     <RequestType>DocGen</RequestType> 
     <Version>10.6</Version> 
     <BankId>01</BankId> 
     <ChannelId>LOS</ChannelId> 
    </Header> 
    <Body> 
     <Data> 
      **<CorpAppLimitDetailsBO> 
      <ApprovedLimitHomeCCY>100.0</ApprovedLimitHomeCCY> 
      <ApprovedLimitCCY>INR</ApprovedLimitCCY> 
      <ApprovedLimit>100.0</ApprovedLimit> 
      <LimitClassification>ROOT</LimitClassification> 
     </CorpAppLimitDetailsBO> 
     <CorpAppLimitDetailsBO> 
      <ApprovedLimitHomeCCY>0.0</ApprovedLimitHomeCCY> 
      <ApprovedLimitCCY/> 
      <ApprovedLimit>500.0</ApprovedLimit> 
      <LimitClassification>CLASSIFICATION1</LimitClassification> 
     </CorpAppLimitDetailsBO> 
     <CorpAppLimitDetailsBO> 
      <ApprovedLimitHomeCCY>100.0</ApprovedLimitHomeCCY> 
      <ApprovedLimitCCY>INR</ApprovedLimitCCY> 
      <ApprovedLimit>100.0</ApprovedLimit> 
      <LimitClassification>CLASSIFICATION1</LimitClassification> 
     </CorpAppLimitDetailsBO> 
     <CorpAppProductDetailsBO> 
      <ProductCategory>3</ProductCategory> 
     </CorpAppProductDetailsBO> 
     <CorpAppProductDetailsBO> 
      <ProductCategory>1</ProductCategory> 
     </CorpAppProductDetailsBO> 
     <CorpAppProductDetailsBO> 
      <ProductCategory>2</ProductCategory> 
      </CorpAppProductDetailsBO>** 
      <TemplateDetails> 
       <Template>tempid001</Template> 
      </TemplateDetails> 
      <SelectedClauses> 
       <Clauses> 
        <Clause>clause1</Clause> 
       </Clauses> 
       <Clauses> 
        <Clause>clause2</Clause> 
       </Clauses> 
       <Clauses> 
        <Clause>clause3</Clause> 
       </Clauses> 
      </SelectedClauses> 
      <Distribution> 
       <Email>[email protected],[email protected],[email protected]</Email> 
       <Print>blrkec3030,blrkec3031</Print> 
      </Distribution> 
     </Data> 
    </Body> 
</FIXML> 

我想使用XSLT將此輸入XML轉換爲另一種XML格式。

下面是我需要的格式,

<FIXML> 
    <Header> 
     <RequestID>ReqID8942</RequestID> 
     <RequestType>DocGen</RequestType> 
     <Version>10.6</Version> 
     <BankId>01</BankId> 
     <ChannelId>LOS</ChannelId> 
    </Header> 
    <Body> 
     <Data> 
      **<LimitDetails> 
      <Limit> 
       <ApprovedLimitHomeCCY>100.0</ApprovedLimitHomeCCY> 
       <ApprovedLimitCCY>INR</ApprovedLimitCCY> 
       <ApprovedLimit>100.0</ApprovedLimit> 
       <LimitClassification>ROOT</LimitClassification> 
      </Limit> 
      <Limit> 
       <ApprovedLimitHomeCCY>0.0</ApprovedLimitHomeCCY> 
       <ApprovedLimitCCY/> 
       <ApprovedLimit>500.0</ApprovedLimit> 
       <LimitClassification>CLASSIFICATION1</LimitClassification> 
      </Limit> 
      <Limit> 
       <ApprovedLimitHomeCCY>100.0</ApprovedLimitHomeCCY> 
       <ApprovedLimitCCY>INR</ApprovedLimitCCY> 
       <ApprovedLimit>100.0</ApprovedLimit> 
       <LimitClassification>CLASSIFICATION1</LimitClassification> 
      </Limit> 
     </LimitDetails> 
     <ProductDetails> 
      <Product> 
       <ProductCategory>3</ProductCategory> 
      </Product> 
      <Product> 
       <ProductCategory>1</ProductCategory> 
      </Product> 
      <Product> 
       <ProductCategory>2</ProductCategory> 
      </Product> 
      </ProductDetails>** 
      <TemplateDetails> 
       <Template>tempid001</Template> 
      </TemplateDetails> 
      <SelectedClauses> 
       <Clauses> 
        <Clause>clause1</Clause> 
       </Clauses> 
       <Clauses> 
        <Clause>clause2</Clause> 
       </Clauses> 
       <Clauses> 
        <Clause>clause3</Clause> 
       </Clauses> 
      </SelectedClauses> 
      <Distribution> 
       <Email>[email protected],[email protected],[email protected]</Email> 
       <Print>blrkec3030,blrkec3031</Print> 
      </Distribution> 
     </Data> 
    </Body> 
</FIXML> 

請幫我,因爲我有完成任務的時間再過2天。

我試着用下面的代碼,我得到了低於輸出,但其餘的標籤爲例如。 <FIXML> , <TemplateDetails>等不是作爲輸出xml的一部分。

XSL下面的代碼:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:output indent="yes" /> <!-- This identity template copies the document --> 
    <xsl:template match="node() | @*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node() | @*" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- 
     This template will only match the 'CorpAppLimitDetailsBO' 
     nodes and modify them the way you want. 
    --> 

<xsl:template match="/*"> 
     <xsl:element name="LimitDetails"> 
      <xsl:for-each select="//CorpAppLimitDetailsBO"> 
       <xsl:element name="Limit"> 
        <xsl:for-each select="*"> 
         <xsl:copy-of select="." /> 
        </xsl:for-each> 
       </xsl:element> 
      </xsl:for-each> 
     </xsl:element> 
     <xsl:element name="ProductDetails"> 
      <xsl:for-each select="//CorpAppProductDetailsBO"> 
       <xsl:element name="Product"> 
        <xsl:for-each select="*"> 
         <xsl:copy-of select="." /> 
        </xsl:for-each> 
       </xsl:element> 
      </xsl:for-each> 
     </xsl:element> 
    </xsl:template> 



</xsl:stylesheet> 

的Output.xml如下:

<?xml version="1.0" encoding="UTF-8"?> 
<LimitDetails> 
<Limit> 
<ApprovedLimitHomeCCY>100.0</ApprovedLimitHomeCCY> 
<ApprovedLimitCCY>INR</ApprovedLimitCCY> 
<ApprovedLimit>100.0</ApprovedLimit> 
<LimitClassification>ROOT</LimitClassification> 
</Limit> 
<Limit> 
<ApprovedLimitHomeCCY>0.0</ApprovedLimitHomeCCY> 
<ApprovedLimitCCY/> 
<ApprovedLimit>500.0</ApprovedLimit> 
<LimitClassification>CLASSIFICATION1</LimitClassification> 
</Limit> 
<Limit> 
<ApprovedLimitHomeCCY>100.0</ApprovedLimitHomeCCY> 
<ApprovedLimitCCY>INR</ApprovedLimitCCY> 
<ApprovedLimit>100.0</ApprovedLimit> 
<LimitClassification>CLASSIFICATION1</LimitClassification> 
</Limit> 
</LimitDetails> 
<ProductDetails> 
<Product> 
<ProductCategory>3</ProductCategory> 
</Product> 
<Product> 
<ProductCategory>1</ProductCategory> 
</Product> 
<Product> 
<ProductCategory>2</ProductCategory> 
</Product> 
</ProductDetails> 

注:子標記(egApprovedLimitHomeCCY ....),我介紹下BO的(例如,用於CorpAppLimitDetailsBO )標籤是動態的。我不應該在xsl中使用硬編碼。請幫助我。

感謝Shil和Sean爲您提供的解決方案。兩者都適合我的要求。但我有一個更懷疑now.i中號再增加一個子標籤<DBApplicantMiscDetails>

<CorpAppProductDetailsBO> 

輸入XML:

<CorpAppProductDetailsBO> 
    <ProductCategory>2</ProductCategory> 
     <DBApplicantMiscDetails> 
      <APPLICANTMISCID>400000</APPLICANTMISCID> 
      <APPLICANTID>400030</APPLICANTID> 
      <MISCTYPE>APPLIED</MISCTYPE> 
     </DBApplicantMiscDetails> 
    </CorpAppProductDetailsBO> 

下面是輸出格式,我期待。

<ProductDetails> 
<Product> 
<ProductCategory>2</ProductCategory> 
<APPLICANTMISCID>400000</APPLICANTMISCID> 
<APPLICANTID>400030</APPLICANTID> 
<MISCTYPE>APPLIED</MISCTYPE> 
</Product> 
</ProductDetails> 

再次感謝。

+0

你可能想,如果你希望有幫助的迴應 – Gratzy

+0

感謝response.I發佈,我試圖 – Moorthy

+0

嘿@Moorthy是代碼先試,並張貼你已經嘗試了什麼,結果你會接受一個答案? –

回答

0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:strip-space elements="*" /> 
<xsl:key name="kDetails" match="* 
    [starts-with(name(),'CorpApp') and 
    substring(name(), string-length(name()) - 8) = 'DetailsBO']" 
     use="substring-before(name(),'DetailsBO')" /> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[*[key('kDetails',substring-before(name(),'DetailsBO'))]]"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*"/> 
    <xsl:apply-templates select="*[generate-id() = 
    generate-id(key('kDetails', 
    substring-before(name(),'DetailsBO'))[1])]" mode="group" /> 
    <xsl:apply-templates select="*[not(
     key('kDetails',substring-before(name(),'DetailsBO')))] 
     |comment()|processing-instruction()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*" mode="group"> 
    <xsl:variable name="group-name" select="substring-after(substring-before(name(),'DetailsBO'),'CorpApp')" /> 
    <xsl:element name="{$group-name}Details"> 
    <xsl:for-each select="key('kDetails',substring-before(name(),'DetailsBO'))"> 
    <xsl:element name="{$group-name}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
    </xsl:for-each> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 
+0

謝謝了許多肖恩。您的解決方案完全符合我的要求,但對我的理解並不容易,因爲我對XSLT很陌生。我將不得不學習XSLT,以便輕鬆理解。我很高興能夠成爲Stackoverflow.i的一員,我立即得到了答案。再次感謝,我有一個疑問。將現在發佈我的問題。 – Moorthy

0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="FIXML"/> 
    </xsl:template> 
    <xsl:template match="FIXML"> 
     <FIXML> 
      <xsl:apply-templates select="Header"/> 
      <xsl:apply-templates select="Body"/> 
     </FIXML> 
    </xsl:template> 
    <xsl:template match="Header"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="Body"> 
     <Body> 
      <xsl:apply-templates select="Data"/> 
     </Body> 
    </xsl:template> 
    <xsl:template match="Data"> 
     <Data> 
      <LimitDetails> 
       <xsl:apply-templates select="CorpAppLimitDetailsBO"/> 
      </LimitDetails> 
      <ProductDetails> 
       <xsl:apply-templates select="CorpAppProductDetailsBO"/> 
      </ProductDetails> 
      <xsl:apply-templates select="TemplateDetails"/> 
      <xsl:apply-templates select="SelectedClauses"/> 
      <xsl:apply-templates select="Distribution"/> 
     </Data> 
    </xsl:template> 
    <xsl:template match="CorpAppLimitDetailsBO"> 
     <Limit> 
      <xsl:copy-of select="child::*"/> 
     </Limit> 
    </xsl:template> 
    <xsl:template match="CorpAppProductDetailsBO"> 
     <xsl:apply-templates select="ProductCategory"/> 
    </xsl:template> 
    <xsl:template match="ProductCategory"> 
     <Product> 
      <xsl:copy-of select="."/> 
     </Product> 
    </xsl:template> 
    <xsl:template match="TemplateDetails"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="SelectedClauses"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="Distribution"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

OP已要求處理名稱以BO結尾的元素,以便進行通用化處理,而不是像您所做的那樣對其進行硬編碼。來自OP:'我在BO(例如CorpAppLimitDetailsBO)標籤下出現的兒童標籤(用於egApprovedLimitHomeCCY ....)是動態的' –

+0

非常感謝Shil。您的解決方案完全符合我的要求。我很高興能夠成爲Stackoverflow.i的一員,我立即得到了答案。再次感謝,我有一個疑問。將現在發佈我的問題。 – Moorthy

+0

嘿@希爾。我發佈了一個更多的查詢,我在下添加了一個更多的子標記。你能幫我解決這個問題嗎? – Moorthy

0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml"/> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="FIXML"/> 
    </xsl:template> 
    <xsl:template match="FIXML"> 
     <FIXML> 
      <xsl:apply-templates select="Header"/> 
      <xsl:apply-templates select="Body"/> 
     </FIXML> 
    </xsl:template> 
    <xsl:template match="Header"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="Body"> 
     <Body> 
      <xsl:apply-templates select="Data"/> 
     </Body> 
    </xsl:template> 
    <xsl:template match="Data"> 
     <Data> 
      <LimitDetails> 
       <xsl:apply-templates select="CorpAppLimitDetailsBO"/> 
      </LimitDetails> 
      <ProductDetails> 
       <xsl:apply-templates select="CorpAppProductDetailsBO"/> 
      </ProductDetails> 
      <xsl:apply-templates select="TemplateDetails"/> 
      <xsl:apply-templates select="SelectedClauses"/> 
      <xsl:apply-templates select="Distribution"/> 
     </Data> 
    </xsl:template> 
    <xsl:template match="CorpAppLimitDetailsBO"> 
     <Limit> 
      <xsl:copy-of select="child::*"/> 
     </Limit> 
    </xsl:template> 
    <xsl:template match="CorpAppProductDetailsBO"> 
    <Product> 
     <xsl:apply-templates select="ProductCategory"/> 
     <xsl:apply-templates select="DBApplicantMiscDetails"/> 
    </Product> 
    </xsl:template> 
    <xsl:template match="ProductCategory"> 
      <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="DBApplicantMiscDetails"> 
    <xsl:copy-of select="child::*"/> 
    </xsl:template> 
    <xsl:template match="TemplateDetails"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="SelectedClauses"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="Distribution"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 
</xsl:stylesheet>