2012-10-08 212 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>