apply two consecutive xslt transformations - xslt

I have two xslt transformations to apply to an xml message.
The first is to drop all namespaces and prefixes. here is the code :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()[not(self::*)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The second one is to select elements from the output of the first :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<onSale><xsl:value-of select="//entry/content/product_product/sale_ok" /></onSale>
<onlineOnly><xsl:value-of select="//entry/content/product_product/online" /></onlineOnly>
<name><xsl:value-of select="//entry/content/product_product/name" /></name>
<isbn><xsl:value-of select="//entry/content/product_product/isbn" /></isbn>
<price><xsl:value-of select="//entry/content/product_product/price" /></price>
<active><xsl:value-of select="//entry/content/product_product/active" /></active>
<format><xsl:value-of select="//entry/content/product_product/format" /></format>
<collection><xsl:value-of select="//entry/content/product_product/collection" /></collection>
<dateParution><xsl:value-of select="//entry/content/product_product/date_parution"/></dateParution>
<ean13><xsl:value-of select="//entry/content/product_product/ean13"/></ean13>
</xsl:template>
</xsl:stylesheet>
How I can apply the two of them in one xslt transformation without doing two transformation separately .
Thanks

I don't know which version of XSLT is supported in your environment, with XSLT 2.0 you can use
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="step1">
<xsl:apply-templates mode="step1"/>
</xsl:variable>
<xsl:template match="#*|node()[not(self::*)]" mode="step1">
<xsl:copy/>
</xsl:template>
<xsl:template match="*" mode="step1">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|#*" mode="step1"/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$step1//entry"/>
</xsl:template>
<xsl:template match="entry">
<onSale><xsl:value-of select="content/product_product/sale_ok" /></onSale>
<onlineOnly><xsl:value-of select="content/product_product/online" /></onlineOnly>
<name><xsl:value-of select="content/product_product/name" /></name>
<isbn><xsl:value-of select="content/product_product/isbn" /></isbn>
<price><xsl:value-of select="content/product_product/price" /></price>
<active><xsl:value-of select="content/product_product/active" /></active>
<format><xsl:value-of select="content/product_product/format" /></format>
<collection><xsl:value-of select="content/product_product/collection" /></collection>
<dateParution><xsl:value-of select="content/product_product/date_parution"/></dateParution>
<ean13><xsl:value-of select="content/product_product/ean13"/></ean13>
</xsl:template>
</xsl:stylesheet>
I would further refactor however and write templates like
<xsl:template match="sale_ok">
<onSale>
<xsl:value-of select="."/>
</onSale>
</xsl:template>
If you use XSLT 1.0 you need an extension function to process the contents of a variable with apply-templates so doing
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="step1">
<xsl:apply-templates mode="step1"/>
</xsl:variable>
<xsl:template match="#*|node()[not(self::*)]" mode="step1">
<xsl:copy/>
</xsl:template>
<xsl:template match="*" mode="step1">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|#*" mode="step1"/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="exsl:node-set($step1)//entry"/>
</xsl:template>
<xsl:template match="entry">
<onSale><xsl:value-of select="content/product_product/sale_ok" /></onSale>
<onlineOnly><xsl:value-of select="content/product_product/online" /></onlineOnly>
<name><xsl:value-of select="content/product_product/name" /></name>
<isbn><xsl:value-of select="content/product_product/isbn" /></isbn>
<price><xsl:value-of select="content/product_product/price" /></price>
<active><xsl:value-of select="content/product_product/active" /></active>
<format><xsl:value-of select="content/product_product/format" /></format>
<collection><xsl:value-of select="content/product_product/collection" /></collection>
<dateParution><xsl:value-of select="content/product_product/date_parution"/></dateParution>
<ean13><xsl:value-of select="content/product_product/ean13"/></ean13>
</xsl:template>
</xsl:stylesheet>
On the other I wonder why we are getting lots of questions recently trying to eliminate namespaces or to ignore them, if you really want to do that with XSLT 2.0 then doing
<xsl:template match="*:sale_ok">
<onSale>
<xsl:value-of select="."/>
<onSale>
</xsl:template>
and so on suffices.

Related

Create copy of record based on node that occurs multiple times

I have a requirement to create a copy of an XML file based on a field that occurs multiple times.
Input XML: There are two EmpEmployment nodes in the XML. I need to separate them and copy the rest of the nodes so that I have two PerPerson records with one EmpEmployment each.
<PerPerson>
<PerPerson>
<personalInfoNav>
<PerPersonal/>
</personalInfoNav>
<nationalIdNav>
<PerNationalId/>
</nationalIdNav>
<personIdExternal>AA</personIdExternal>
<personEmpTerminationInfoNav>
<PersonEmpTerminationInfo/>
</personEmpTerminationInfoNav>
<phoneNav>
<PerPhone/>
</phoneNav>
<employmentNav>
<EmpEmployment>
<compInfoNav>
<EmpCompensation/>
</compInfoNav>
<jobInfoNav>
<EmpJob/>
</jobInfoNav>
</EmpEmployment>
<EmpEmployment>
<compInfoNav>
<EmpCompensation/>
</compInfoNav>
<jobInfoNav>
<EmpJob/>
</jobInfoNav>
</EmpEmployment>
</employmentNav>
<homeAddressNavDEFLT>
<PerAddressDEFLT/>
</homeAddressNavDEFLT>
</PerPerson>
</PerPerson>
I am trying to do this using XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hci="http://sap.com/it/" exclude-result-prefixes="hci">
<xsl:strip-space elements="*"/>
<xsl:output encoding="utf-8" indent="yes" method="xml"/>
<xsl:template match="/">
<PerPerson>
<xsl:for-each select="PerPerson/PerPerson">
<xsl:variable name="var_person" select="./*[not(name()='EmpEmployment')]"/>
<xsl:for-each select="employmentNav/EmpEmployment">
<xsl:variable name="var_empInfo" select="."/>
<PerPerson>
<xsl:copy-of select="$var_person"/>
<xsl:copy-of select="$var_empInfo"/>
</PerPerson>
</xsl:for-each>
</xsl:for-each>
</PerPerson>
</xsl:template>
</xsl:stylesheet>
Its not working as expected. I am unable to create the desired output below:
<PerPerson>
<PerPerson>
<personalInfoNav>
<PerPersonal/>
</personalInfoNav>
<nationalIdNav>
<PerNationalId/>
</nationalIdNav>
<personIdExternal>AA</personIdExternal>
<personEmpTerminationInfoNav>
<PersonEmpTerminationInfo/>
</personEmpTerminationInfoNav>
<phoneNav>
<PerPhone/>
</phoneNav>
<employmentNav>
<EmpEmployment>
<compInfoNav>
<EmpCompensation/>
</compInfoNav>
<jobInfoNav>
<EmpJob/>
</jobInfoNav>
</EmpEmployment>
</employmentNav>
<homeAddressNavDEFLT>
<PerAddressDEFLT/>
</homeAddressNavDEFLT>
</PerPerson>
<PerPerson>
<personalInfoNav>
<PerPersonal/>
</personalInfoNav>
<nationalIdNav>
<PerNationalId/>
</nationalIdNav>
<personIdExternal>AA</personIdExternal>
<personEmpTerminationInfoNav>
<PersonEmpTerminationInfo/>
</personEmpTerminationInfoNav>
<phoneNav>
<PerPhone/>
</phoneNav>
<employmentNav>
<EmpEmployment>
<compInfoNav>
<EmpCompensation/>
</compInfoNav>
<jobInfoNav>
<EmpJob/>
</jobInfoNav>
</EmpEmployment>
</employmentNav>
<homeAddressNavDEFLT>
<PerAddressDEFLT/>
</homeAddressNavDEFLT>
</PerPerson>
</PerPerson>
You could do:
XSLT 1.0
<xsl:stylesheet version="1.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="/PerPerson">
<PerPerson>
<xsl:for-each select="PerPerson/employmentNav/EmpEmployment">
<PerPerson>
<xsl:copy-of select="../preceding-sibling::*"/>
<employmentNav>
<xsl:copy-of select="."/>
</employmentNav>
<xsl:copy-of select="../following-sibling::*"/>
</PerPerson>
</xsl:for-each>
</PerPerson>
</xsl:template>
</xsl:stylesheet>
In XSLT 2.0 you can use tunnel-parameters.
And then just use the template macht engine like below
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:template match="#*|node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="#*|node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PerPerson/PerPerson">
<xsl:variable name="person" select="."/>
<xsl:for-each select="employmentNav/EmpEmployment">
<xsl:apply-templates select="$person" mode="denormalize">
<xsl:with-param name="position" as="xs:integer" select="position()" tunnel="yes"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="employmentNav" mode="denormalize">
<xsl:param name="position" as="xs:integer" tunnel="yes"/>
<xsl:copy>
<xsl:apply-templates select="EmpEmployment[$position]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Error while assigning XML attribute value in XSLT

My input XML is as below:
<MessageOutput Status="2">
<Source>External</Source>
<Error>Server not reachable</Error>
<LineNo>0</LineNo>
</MessageOutput>
My requirement is to write XSLT and check if <Error> tag has value "Server not reachable" and if yes then change the Status attribute value to "3".
I wrote below code but getting error:
"XSLT Error: Open quote is expected for attribute "{1}" associated
with an element type "Status"."
Please assist.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1"/>
<xsl:variable name="Des" select="'Server not reachable'"/>
<xsl:variable name="Err" select="MessageOutput/Error"/>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="#*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="/MessageOutput">
<xsl:choose>
<xsl:when test="$Des=$Err">
<MessageOutput Status="3">
<xsl:apply-templates/>
</MessageOutput>
</xsl:when>
<xsl:otherwise>
<MessageOutput Status=<xsl:value-of select="#Status"/>>
<xsl:apply-templates/>
</MessageOutput>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Try this:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1"/>
<xsl:variable name="Des" select="'Server not reachable'"/>
<xsl:variable name="Err" select="MessageOutput/Error"/>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/MessageOutput">
<xsl:choose>
<xsl:when test="$Des=$Err">
<MessageOutput Status="3">
<xsl:apply-templates/>
</MessageOutput>
</xsl:when>
<xsl:otherwise>
<MessageResult Status="{#Status}">
<xsl:apply-templates/>
</MessageResult>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Or shortly:
<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:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="MessageOutput[Error='Server not reachable']/#Status">
<xsl:attribute name="Status">3</xsl:attribute>
</xsl:template>
</xsl:stylesheet>

How to remove the rootnodes using XSLT?

Input file:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:root xmlns:ns0="http://xyz.com/separate">
<ns0:root1>
<ns3:Detail xmlns:ns3="http://POProject/Details">
<DetailLines>
<ItemID>
<ItemDescription/>
</DetailLines>
</ns3:Detail>
</ns0:root1>
</ns0:root>
Output file:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Detail xmlns:ns0="http://POProject/Details">
<DetailLines>
<ItemID>
<ItemDescription/>
</DetailLines>
</ns0:Detail>
Question: I have to remove the root1 and root nodes and need to do small
changes in Detail node. How to write a xslt code to achieve this?
This...
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://xyz.com/separate"
xmlns:ns3="http://POProject/Details">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="*/*/ns3:Detail" />
</xsl:template>
<xsl:template match="ns3:Detail">
<xsl:apply-templates select="." mode="copy-sans-namespace" />
</xsl:template>
<xsl:template match="*" mode="copy-sans-namespace">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates mode="copy-sans-namespace" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
...will yield this...
<?xml version="1.0" encoding="utf-8"?>
<ns3:Detail xmlns:ns3="http://POProject/Details">
<DetailLines>
<ItemID />
<ItemDescription />
</DetailLines>
</ns3:Detail>
I'm not sure it is possible to control the prefix. The XDM data model does not consider it to be significant information.
UDPATE
To get the prefix rename, I thought you would have to go to an XML 1.1 supporting XSLT processor (allowing prefix undefine), but I found a way to do it with XML 1.0 . Try this ...
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://xyz.com/separate">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/" xmlns:ns3="http://POProject/Details">
<xsl:apply-templates select="*/*/ns3:Detail" />
</xsl:template>
<xsl:template match="ns0:Detail" xmlns:ns0="http://POProject/Details">
<ns0:Detail xmlns:ns0="http://POProject/Details">
<xsl:apply-templates select="*" mode="copy-sans-namespace" />
</ns0:Detail>
</xsl:template>
<xsl:template match="*" mode="copy-sans-namespace">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates mode="copy-sans-namespace" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Remove xsi:type using xslt

I have following XML. I was able to remove all namespaces but not able to remove xsi:type using XSL.
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<StudentResult xmlns='http://ns.xyz.org/2004-08-02' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:ns1='http://ns.xyz.org/2004-08-02' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:type='ns1:StudentResult'>
<StudentId idOwner='xyz'><IdValue name='ClientId'>9103-XML</IdValue></StudentId>
<ClientOrderId idOwner='Cloud'><IdValue name='OrderNumber'>272454</IdValue></ClientOrderId>
<Results>false</Results>
</StudentResult>
Desired Output:
<?xml version="1.0" encoding="utf-8"?>
<StudentResult>
<StudentId idOwner="xyz"><IdValue name="ClientId">9103-XML</IdValue></StudentId>
<ClientOrderId idOwner="Cloud"><IdValue name="OrderNumber">272454</IdValue></ClientOrderId>
<Results>false</Results>
</StudentResult>
This is the xslt I used but it did not help.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" encoding="utf-8" />
<xsl:template match="/|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="#*|node()|processing-instruction()"/>
</xsl:template>
</xsl:stylesheet>
Add a template
<xsl:template match="#xsi:type"/>
plus
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsi">
on the stylesheet's root element.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()[not(self::*)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#*[not(name()='xsi:type')]|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<StudentResult
xmlns='http://ns.xyz.org/2004-08-02'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:ns1='http://ns.xyz.org/2004-08-02'
xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:type='ns1:StudentResult'>
<StudentId idOwner='xyz'>
<IdValue name='ClientId'>9103-XML</IdValue>
</StudentId>
<ClientOrderId idOwner='Cloud'>
<IdValue name='OrderNumber'>272454</IdValue>
</ClientOrderId>
<Results>false</Results>
</StudentResult>
produces the wanted, correct result:
<StudentResult>
<StudentId idOwner="xyz">
<IdValue name="ClientId">9103-XML</IdValue>
</StudentId>
<ClientOrderId idOwner="Cloud">
<IdValue name="OrderNumber">272454</IdValue>
</ClientOrderId>
<Results>false</Results>
</StudentResult>

Remove elements based on other element's value -- XSLT

I have a style-sheet that I am using to remove certain elements based on the value of an other element. However, it is not working ...
Sample Input XML
<Model>
<Year>1999</Year>
<Operation>ABC</Operation>
<Text>Testing</Text>
<Status>Ok</Status>
</Model>
If Operation value is 'ABC' then remove Text and Status nodes from XML.
And gives the following output.
<Model>
<Year>1999</Year>
<Operation>ABC</Operation>
</Model>
Here is my style sheet that I am using but it is removing Text and Status nodes from all XMLs even when operation is not 'ABC'.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="ID" select="//Operation"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Text | Status">
<xsl:if test ="$ID ='ABC'">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Thanks in Advance
How would I do the same when namespace is present like
<ns0:next type="Sale" xmlns:ns0="http://Test.Schemas.Inside_Sales">
Here is a complete XSLT transformation -- short and simple (no variables, no xsl:if, xsl:choose, xsl:when, xsl:otherwise):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[Operation='ABC']/Text | *[Operation='ABC']/Status"/>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<Model>
<Year>1999</Year>
<Operation>ABC</Operation>
<Text>Testing</Text>
<Status>Ok</Status>
</Model>
the wanted, correct result is produced:
<Model>
<Year>1999</Year>
<Operation>ABC</Operation>
</Model>
Change your xsl:if as follows:
<xsl:if test="../Operation!='ABC'">
and you can get rid of xsl:variable.
A better pattern in XSLT than using <xsl:if> is to add new templates with match conditions:
<xsl:template match="(Text | Status)[../Operation != 'ABC']"/>
I found this works:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Model">
<xsl:choose>
<xsl:when test="Operation[text()!='ABC']">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="Year"/>
<xsl:apply-templates select="Operation"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>