Kacper Perschke
Kacper Perschke

Reputation: 179

Copy xml attribute in XSLT

I would like to copy the attribute value from input to output.

Place of attribute in input is: katz-request/request/statebond-buy/payment/amount/@curr

Place of attribute in output is: katz-reply/reply/statebond-buy/amount/@curr

Here goes input xml

<?xml version="1.0" encoding="ISO-8859-2" standalone="yes"?>
<katz-request>
   <request>
      <statebond-buy>
         <isin>PL0000108155</isin>
         <name>DOS0616</name>
         <count>2</count>
         <pay-date>2014-06-18</pay-date>
         <payment>
            <amount curr="PLN">200.00</amount>
         </payment>
      </statebond-buy>
   </request>
</katz-request>

Here goes my transformation

<?xml version="1.0" encoding="iso-8859-2" standalone="yes"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="iso-8859-2" indent="yes" standalone="yes"/>
    <xsl:template match="/">
        <katz-reply>
            <reply>
                <statebond-buy>
                    <count>
                        <xsl:value-of select="katz-request/request/statebond-buy/count"/>
                    </count>
                    <amount curr="DEM">
                        <xsl:value-of select="katz-request/request/statebond-buy/payment/amount"/>
                    </amount>
                    <tx-id>843084</tx-id>
                    <day-ref-id>837</day-ref-id>
                    <appl-id>000000000002267</appl-id>
                </statebond-buy>
            </reply>
        </katz-reply>
    </xsl:template>
</xsl:transform>

Here is the result

<?xml version="1.0" encoding="iso-8859-2" standalone="yes"?>
<katz-reply>
  <reply>
    <statebond-buy>
      <count>2</count>
      <amount curr="DEM">200.00</amount>
      <tx-id>843084</tx-id>
      <day-ref-id>837</day-ref-id>
      <appl-id>000000000002267</appl-id>
    </statebond-buy>
  </reply>
</katz-reply>

that holds "DEM" instead of "PLN".

Upvotes: 0

Views: 127

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117140

How about a simple one:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="iso-8859-2" indent="yes"/>

<xsl:template match="/">
    <katz-reply>
        <reply>
            <xsl:for-each select="katz-request/request/statebond-buy">
                <statebond-buy>
                    <xsl:copy-of select="count | payment/amount"/>
                    <tx-id>843084</tx-id>
                    <day-ref-id>837</day-ref-id>
                    <appl-id>000000000002267</appl-id>
                </statebond-buy>
            </xsl:for-each>             
        </reply>
    </katz-reply>
</xsl:template>

</xsl:stylesheet>

Upvotes: 2

Tim C
Tim C

Reputation: 70648

You could make use of "Attribute Value Templates" here, and write out your XML like this

        <amount curr="{katz-request/request/statebond-buy/payment/amount/@curr}">
            <xsl:value-of select="katz-request/request/statebond-buy/payment/amount"/>
        </amount>

The curly braces indicate an expression to be evaluated, not output literally.

But much better would be to re-write your XSLT to use the XSLT Identity Template, and then it is just a case of copying across whole nodes.

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="iso-8859-2" indent="yes" standalone="yes"/>

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

    <xsl:template match="statebond-buy">
        <statebond-buy>
            <xsl:apply-templates select="count" />
            <xsl:apply-templates select="payment/amount" />
            <tx-id>843084</tx-id>
            <day-ref-id>837</day-ref-id>
            <appl-id>000000000002267</appl-id>
        </statebond-buy>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 3

Related Questions