简体   繁体   中英

How to get XML attribute value's using 'xsl:apply-templates' in XSLT

I have the following XML and would like to get the value of XML attribute code="MA" from <FullNameVerifiesToAddress> node and <FullNameVerifiesToSSN> node into the node <Summary> .

<PreciseIDServer>
    <Header>
        <ReportDate>09042018</ReportDate>
        <ReportTime>235641</ReportTime>
    </Header>
    <Summary>
        <TransactionID>1421957889</TransactionID>
        <InitialDecision>ACC</InitialDecision>
        <FinalDecision>ACC</FinalDecision>
        <CrossReferenceIndicatorsGrid>
            <FullNameVerifiesToAddress code="MA"/>
            <FullNameVerifiesToSSN code="MA"/>
        </CrossReferenceIndicatorsGrid>
    </Summary>
</PreciseIDServer>

I use the following XSLT right now to get the <ReportTime> from <Header> node into <summary> but I also need the above mentioned attributes in the Summary node.

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

the XML i want as OUTPUT should be something like

<PreciseIDServer>
    <Header>
        <ReportDate>09042018</ReportDate>
        <ReportTime>235641</ReportTime>
    </Header>
    <Summary>
        <TransactionID>1421957889</TransactionID>
        <InitialDecision>ACC</InitialDecision>
        <FinalDecision>ACC</FinalDecision>
        <ReportTime>235641</ReportTime>
        <FullNameVerifiesToAddress>MA </FullNameVerifiesToAddress>
        <FullNameVerifiesToSSN> MA </FullNameVerifiesToSSN>
        <CrossReferenceIndicatorsGrid>
            <FullNameVerifiesToAddress code="MA"/>
            <FullNameVerifiesToSSN code="MA"/>
        </CrossReferenceIndicatorsGrid>
    </Summary>
</PreciseIDServer>

I think you need to push some nodes through a second mode as you want to output them once uncopied while you also want to transform them, so a minimal XSLT 3 solution would be

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

    <xsl:template match="CrossReferenceIndicatorsGrid">
        <xsl:apply-templates mode="code-att-to-content"/>
        <xsl:next-match/>
    </xsl:template>

    <xsl:template match="CrossReferenceIndicatorsGrid/*" mode="code-att-to-content">
        <xsl:copy>{@code}</xsl:copy>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bdxtqL

For XSLT 2 you would need to replace the xsl:mode declaration with the identity transformation template

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

and the text value template {@code} with an <xsl:value-of select="@code"/> .

For XSLT 1 you need the same changes as for XSLT 2 but additionally need to put a name on the identity template (ie change <xsl:template match="@* | node()"> to <xsl:template match="@* | node()" name="identity"> ) and replace the use of <xsl:next-match/> with <xsl:call-template name="identity"/> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM