XSL身份拷贝

时间:2013-10-02 00:17:16

标签: xml xslt xpath

我有以下XML

<ExternalAssessmentRequest >
    <ApplicationData Lender="TEST">
        <LiabilityList>
            <RequestedLoan Identifier="New1" BaseAmount="250000">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
                <Feature Code="SupaPackage"/>
            </RequestedLoan>
            <ExistingLoan Identifier="Existing1" Clearing="Yes" >
                <Security RelatedIdentifier="Asset1"/>
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </ExistingLoan>
            <OtherLiability Identifier="Liability1" CreditCard="Yes" >
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </OtherLiability>
            <Expense Identifier="Expense1" Type="Transport" >
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Expense>
        </LiabilityList>
        <AssetList>
            <Asset Identifier="Asset1" Security="Yes" >
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Asset>
            <Fund Identifier="Fund1" Amount="1000" Description="Slush Fund"/>
        </AssetList>
        <IncomeList>
            <Income Identifier="Income1" GrossAmount="80000" >
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Income>
        </IncomeList>
        <ApplicantList>
            <Household Children="0" AdditionalAdults="0" Postcode="2000" Description="1 Test St, Sydney" Boarding="Yes">
                <Person Identifier="Applicant1" Name="John Test" />
                <Person Identifier="Applicant2" Name="Jane Test" />
            </Household>
            <Company Identifier="Company1" Name="Tardis">
                <Director RelatedIdentifier="Applicant1"/>
            </Company>
        </ApplicantList>
        <FeeList>
            <Fee Identifier="Fee1" Amount="100" PaidAmount="0" />
        </FeeList>
    </ApplicationData>
    <AdditionalAssessment Lender="TESTLender">
        <RequestedLoan Product="Supa Variable" ProductID="ProductA"/>
    </AdditionalAssessment>
    <AdditionalAssessment Lender="TEST1">
        <RequestedLoan Product="Supa Variable" ProductID="ProductB"/>
    </AdditionalAssessment>
    <AdditionalAssessment Lender="TEST2">
        <RequestedLoan Product="Supa Variable" ProductID="ProductC"/>
    </AdditionalAssessment>
    <AdditionalAssessment Lender="TEST3">
        <RequestedLoan Product="Supa Variable" ProductID="ProductD"/>
    </AdditionalAssessment>
    <AdditionalAssessment Lender="TEST4">
        <RequestedLoan Product="Supa Variable" ProductID="ProductD"/>
    </AdditionalAssessment>
</ExternalAssessmentRequest>

我有这个样式表:

<?xml version="1.0" encoding="ascii"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl">
    <xsl:output omit-xml-declaration="yes" method="xml" encoding="UTF-8"/>
    <!--remember the location of the additional assessment information-->
    <xsl:variable name="additional" select="/*/AdditionalAssessment"/>
    <xsl:template match="ApplicationData">
        <!--preserve original data-->
        <xsl:copy-of select="."/>
        <!--now make duplicate-->
        <ApplicationData>
            <!--preserve data attributes-->
            <xsl:copy-of select="@*"/>
            <!--override with additional attributes-->
            <xsl:copy-of select="$additional/@*"/>
            <!--process children looking for modifications to attributes-->
            <xsl:apply-templates select="node()" mode="overrideAttributes"/>
        </ApplicationData>
    </xsl:template>
    <!--copy the element and override attributes form the additional assessment-->
    <xsl:template match="*" mode="overrideAttributes">
        <xsl:copy>
            <!--preserve data attributes-->
            <xsl:copy-of select="@*"/>
            <!--override with additional attributes-->
            <xsl:copy-of select="$additional/*[name(.)=name(current())]/@*"/>
            <!--manipulate the descendants-->
            <xsl:apply-templates mode="overrideAttributes"/>
        </xsl:copy>
    </xsl:template>
    <!--remove the original additional assessment-->
    <xsl:template match="AdditionalAssessment"/>
    <xsl:template match="@*|node()">
        <!--identity for all other nodes-->
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/ExternalAssessmentRequest">
        <xsl:element name="ApplicationDataBatch">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

产生以下输出:

<ApplicationDataBatch>
    <ApplicationData Lender="TEST">
        <LiabilityList>
            <RequestedLoan Identifier="New1" BaseAmount="250000">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
                <Feature Code="SupaPackage"/>
            </RequestedLoan>
            <ExistingLoan Identifier="Existing1" Clearing="Yes">
                <Security RelatedIdentifier="Asset1"/>
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </ExistingLoan>
            <OtherLiability Identifier="Liability1" CreditCard="Yes">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </OtherLiability>
            <Expense Identifier="Expense1" Type="Transport">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Expense>
        </LiabilityList>
        <AssetList>
            <Asset Identifier="Asset1" Security="Yes">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Asset>
            <Fund Identifier="Fund1" Amount="1000" Description="Slush Fund"/>
        </AssetList>
        <IncomeList>
            <Income Identifier="Income1" GrossAmount="80000">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Income>
        </IncomeList>
        <ApplicantList>
            <Household Children="0" AdditionalAdults="0" Postcode="2000" Description="1 Test St, Sydney" Boarding="Yes">
                <Person Identifier="Applicant1" Name="John Test"/>
                <Person Identifier="Applicant2" Name="Jane Test"/>
            </Household>
            <Company Identifier="Company1" Name="Tardis">
                <Director RelatedIdentifier="Applicant1"/>
            </Company>
        </ApplicantList>
        <FeeList>
            <Fee Identifier="Fee1" Amount="100" PaidAmount="0"/>
        </FeeList>
    </ApplicationData>
    <ApplicationData Lender="TEST4">
        <LiabilityList>
            <RequestedLoan Identifier="New1" BaseAmount="250000" Product="Supa Variable" ProductID="ProductD">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
                <Feature Code="SupaPackage"/>
            </RequestedLoan>
            <ExistingLoan Identifier="Existing1" Clearing="Yes">
                <Security RelatedIdentifier="Asset1"/>
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </ExistingLoan>
            <OtherLiability Identifier="Liability1" CreditCard="Yes">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </OtherLiability>
            <Expense Identifier="Expense1" Type="Transport">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Expense>
        </LiabilityList>
        <AssetList>
            <Asset Identifier="Asset1" Security="Yes">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Asset>
            <Fund Identifier="Fund1" Amount="1000" Description="Slush Fund"/>
        </AssetList>
        <IncomeList>
            <Income Identifier="Income1" GrossAmount="80000">
                <Applicant RelatedIdentifier="Applicant1" Percentage="0.5"/>
                <Applicant RelatedIdentifier="Applicant2" Percentage="0.5"/>
            </Income>
        </IncomeList>
        <ApplicantList>
            <Household Children="0" AdditionalAdults="0" Postcode="2000" Description="1 Test St, Sydney" Boarding="Yes">
                <Person Identifier="Applicant1" Name="John Test"/>
                <Person Identifier="Applicant2" Name="Jane Test"/>
            </Household>
            <Company Identifier="Company1" Name="Tardis">
                <Director RelatedIdentifier="Applicant1"/>
            </Company>
        </ApplicantList>
        <FeeList>
            <Fee Identifier="Fee1" Amount="100" PaidAmount="0"/>
        </FeeList>
    </ApplicationData>
</ApplicationDataBatch>

一切都应该只是缺少一件事。 我需要为每个AdditionalAssessment节点创建一个ApplicationData节点。当前样式表仅创建一个而不是5(+1原始应用程序数据)。 样式表需要为每个AdditionalAssessment节点创建ApplicationData节点,只需更改每个附加评估中指定的元素。

2 个答案:

答案 0 :(得分:2)

此XSLT样式表似乎可以执行您想要的操作:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl">
  <xsl:output omit-xml-declaration="yes" method="xml" encoding="UTF-8"/>

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

  <!-- When we get to AdditionalAssessment elements, match the ApplicationData element again in override-attributes
       mode, passing through the AdditionalAssessment element so we can copy things from it. -->
  <xsl:template match="AdditionalAssessment">
    <xsl:apply-templates select="../ApplicationData" mode="override-attributes">
      <xsl:with-param name="additional" select="."/>
    </xsl:apply-templates>
  </xsl:template>

  <!-- Copying out elements and modifying their attributes according to the 'additional' element we pass in as a
       parameter. -->
  <xsl:template match="node()|@*" mode="override-attributes">
    <xsl:param name="additional" />
    <xsl:copy>
      <!-- Preserve data attributes. -->
      <xsl:copy-of select="@*"/>

      <!--Override with additional attributes. -->
      <xsl:copy-of select="$additional/*[name(.)=name(current())]/@*"/>

      <!-- Override the lender if this is the ApplicationData element. A bit annoying to have to do this, but I couldn't 
           get it to work in a nicer way. -->
      <xsl:if test="self::ApplicationData">
        <xsl:copy-of select="$additional/@Lender"/>
      </xsl:if>

      <!-- Manipulate the descendants, excluding the attributes because we've already copied/overridden them. -->
      <xsl:apply-templates select="node()" mode="override-attributes">
        <xsl:with-param name="additional" select="$additional"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

假设原始文档只有一个ApplicationData元素是否安全?如果是这样,那么这应该可以解决问题:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                exclude-result-prefixes="xsl">
  <xsl:output omit-xml-declaration="yes" method="xml" encoding="UTF-8"/>

  <xsl:template match="@*|node()">
    <!--identity for all other nodes-->
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

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

  <xsl:template match="AdditionalAssessment">
    <xsl:apply-templates select ="../ApplicationData" mode="overrideAttributes">
      <xsl:with-param name="additional" select="." />
    </xsl:apply-templates>
  </xsl:template>

  <!--copy the element and override attributes form the additional assessment-->
  <xsl:template match="*" mode="overrideAttributes">
    <xsl:param name="additional" />

    <xsl:variable name="currentIsAD" select="self::ApplicationData" />

    <xsl:copy>
      <!--preserve data attributes-->
      <xsl:copy-of select="@*"/>
      <!--override with additional attributes-->
      <xsl:copy-of select="$additional[$currentIsAD]/@*"/>

      <xsl:copy-of 
          select="$additional[not($currentIsAD)]/*[name(.)=name(current())]/@*"/>
      <!--manipulate the descendants-->
      <xsl:apply-templates mode="overrideAttributes">
        <xsl:with-param name="additional" select="$additional" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>