Retain unmatched nodes in apply templates - xslt

I have a requirement to sort records based on a field (account) only if the another field (depositvalue)is not blank. I am able to do this but my current xslt is removing unmatched nodes in apply templates. How can always leave everything else untouched in this case. The record to be sorted (DirectDeposit) may not always be there for some Employees.
I already made progress on the sorting.
XSLT:
<xsl:stylesheet version = '1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Employee">
<Employee>
<xsl:apply-templates select="DirectDeposit[not(depositvalue = '')]" >
<xsl:sort select="account"/>
</xsl:apply-templates>
<xsl:apply-templates select="DirectDeposit[depositvalue = '']"/>
</Employee>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
actual result: (employee header is gone)
<?xml version="1.0"?>
<Hire>
<Employee>
<DirectDeposit>
<action>DirectDeposit</action>
<created_by/>
<created_on_timestamp>2018-07-13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<account>2</account>
<depositvalue>200</depositvalue>
</DirectDeposit>
<DirectDeposit>
<action>DirectDeposit</action>
<created_by/>
<created_on_timestamp>2018-07-13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<account>3</account>
<depositvalue>100</depositvalue>
</DirectDeposit>
<DirectDeposit>
<action>DirectDeposit</action>
<created_by/>
<created_on_timestamp>2018-07-13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<account>1</account>
<depositvalue/>
</DirectDeposit>
</Employee>
<Employee/>
</Hire>
Expected:
<?xml version="1.0"?>
<Hire>
<Employee>
<Header>
<action/>
<created_by/>
<created_on_timestamp>2018-07-
13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<AdditionalElements/>
</Header>
<DirectDeposit>
<action>DirectDeposit</action>
<created_by/>
<created_on_timestamp>2018-07-
13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<account>2</account>
<depositvalue>200</depositvalue>
</DirectDeposit>
<DirectDeposit>
<action>DirectDeposit</action>
<created_by/>
<created_on_timestamp>2018-07-13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<account>3</account>
<depositvalue>100</depositvalue>
</DirectDeposit>
<DirectDeposit>
<action>DirectDeposit</action>
<created_by/>
<created_on_timestamp>2018-07-13T19:46:58.000Z</created_on_timestamp>
<date_of_birth>1985-04-09</date_of_birth>
<account>1</account>
<depositvalue/>
</DirectDeposit>
</Employee>
<Employee/>

Add
<xsl:apply-templates select="Header"/>
to your match="Employee" template. If you don't process the Header element, it won't be processed, and will therefore be absent from the output.

Related

Attempting to remove element and reorder elements in resulting document

I have the following XML and XSLT.
I am attempting to exclude the NotUsed2 element from the resulting document.
I need to reorder the resulting so that AutoTypesetInfo follows NotUsed3.
XML:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<Plan xmlns="http://www.ccieurope.com/xmlns/CCIPlanner">
<Header>
<Update>0</Update>
<NewsPaper>Pub1</NewsPaper>
<Date>080818</Date>
<Zone>MAIN</Zone>
<Edition>1st</Edition>
<Pages>26</Pages>
<Section>A B C </Section>
<Number>08082018</Number>
<Format>
<Height>21.70i</Height>
<Width>9.87i</Width>
</Format>
<PrintingInfo/>
<Version/>
<Config/>
<Default/>
<FileFormat>2.0</FileFormat>
<IssueName/>
</Header>
<Page>
<PhysicalBook>A</PhysicalBook>
<BookPageNumber>1</BookPageNumber>
<Desk>A</Desk>
<SubDesk/>
<SpreadPage>0</SpreadPage>
<Status/>
<Deadline>0708182230</Deadline>
<PagePrintInfo/>
<Cmyk>CMYK</Cmyk>
<Spot1/>
<Spot2/>
<Spot3/>
<CyanFilm/>
<MagFilm/>
<YelFilm/>
<BlackFilm/>
<Spot1Film/>
<Spot2Film/>
<Spot3Film/>
<PageId>MAIN#F</PageId>
<TemplatePage>
<Content>c#FolioStandard#i#</Content>
<Layout></Layout>
</TemplatePage>
<ProdForm/>
<TextSourceDir/>
<TextSourcePage/>
<RunningPage/>
<CmyDeadline/>
<ColorGrp/>
<AdRules>1</AdRules>
<CustChar/>
<CustDate/>
<Active>1</Active>
<NoMaster>0</NoMaster>
<Cust2/>
<PageType>EditorialOnly</PageType>
<Cust4/>
<Cust5/>
<Cust6/>
<Cust7/>
<Cust8/>
<Cust9/>
<Cust10/>
<Desk2/>
<Desk2NewsHole/>
<Desk2Placement/>
<Cust11/>
<NotUsed2/>
<NotUsed3/>
<Ad>
<BookingNumber>12345</BookingNumber>
<Description>Desc1</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>Proces</AdColor>
<AdWidth>710.9</AdWidth>
<AdHeight>144.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>0.00</XPos>
<YPos>1404.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
<AutoTypesetInfo>0:5-60</AutoTypesetInfo></Page>
<Page>
<PhysicalBook>A</PhysicalBook>
<BookPageNumber>2</BookPageNumber>
<Desk>A</Desk>
<SubDesk/>
<SpreadPage>0</SpreadPage>
<Status/>
<Deadline>0708182230</Deadline>
<PagePrintInfo/>
<Cmyk>CMYK</Cmyk>
<Spot1/>
<Spot2/>
<Spot3/>
<CyanFilm/>
<MagFilm/>
<YelFilm/>
<BlackFilm/>
<Spot1Film/>
<Spot2Film/>
<Spot3Film/>
<PageId>MAIN#1</PageId>
<TemplatePage>
<Content>c#FolioStandard#i#</Content>
<Layout></Layout>
</TemplatePage>
<ProdForm/>
<TextSourceDir/>
<TextSourcePage/>
<RunningPage/>
<CmyDeadline/>
<ColorGrp/>
<AdRules>1</AdRules>
<CustChar/>
<CustDate/>
<Active>1</Active>
<NoMaster>0</NoMaster>
<Cust2/>
<PageType>Mixed</PageType>
<Cust4/>
<Cust5/>
<Cust6/>
<Cust7/>
<Cust8/>
<Cust9/>
<Cust10/>
<Desk2/>
<Desk2NewsHole/>
<Desk2Placement/>
<Cust11/>
<NotUsed2/>
<NotUsed3/>
<Ad>
<BookingNumber>152345</BookingNumber>
<Description>Description</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>000K</AdColor>
<AdWidth>351.9</AdWidth>
<AdHeight>360.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>0.00</XPos>
<YPos>1188.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
<Ad>
<BookingNumber>12345</BookingNumber>
<Description>Description</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>Proces</AdColor>
<AdWidth>351.9</AdWidth>
<AdHeight>360.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>358.99</XPos>
<YPos>1188.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
<AutoTypesetInfo>0:5-60</AutoTypesetInfo>
</Page>
</Plan>
XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cci="http://www.ccieurope.com/xmlns/CCIPlanner"
exclude-result-prefixes="msxsl cci"
>
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- If element name match on NotUsed2, exclude from result -->
<xsl:template match="NotUsed2" />
</xsl:stylesheet>
Expected in the resulting Page node:
<Page>
<PhysicalBook>A</PhysicalBook>
<BookPageNumber>1</BookPageNumber>
<Desk>A</Desk>
<SubDesk/>
<SpreadPage>0</SpreadPage>
<Status/>
<Deadline>0708182230</Deadline>
<PagePrintInfo/>
<Cmyk>CMYK</Cmyk>
<Spot1/>
<Spot2/>
<Spot3/>
<CyanFilm/>
<MagFilm/>
<YelFilm/>
<BlackFilm/>
<Spot1Film/>
<Spot2Film/>
<Spot3Film/>
<PageId>MAIN#F</PageId>
<TemplatePage>
<Content>c#FolioStandard#i#</Content>
<Layout></Layout>
</TemplatePage>
<ProdForm/>
<TextSourceDir/>
<TextSourcePage/>
<RunningPage/>
<CmyDeadline/>
<ColorGrp/>
<AdRules>1</AdRules>
<CustChar/>
<CustDate/>
<Active>1</Active>
<NoMaster>0</NoMaster>
<Cust2/>
<PageType>EditorialOnly</PageType>
<Cust4/>
<Cust5/>
<Cust6/>
<Cust7/>
<Cust8/>
<Cust9/>
<Cust10/>
<Desk2/>
<Desk2NewsHole/>
<Desk2Placement/>
<Cust11/>
<NotUsed3/>
<AutoTypesetInfo>0:5-60</AutoTypesetInfo>
<Ad>
<BookingNumber>12345</BookingNumber>
<Description>Desc1</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>Proces</AdColor>
<AdWidth>710.9</AdWidth>
<AdHeight>144.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>0.00</XPos>
<YPos>1404.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
</Page>
I can't get the code to exclude the NotUsed2 element.
I'm not sure where to begin to tackle reordering the elements within nodes.
Any help would be appreciated.
Your NotUsed2 is not being removed because you have not accounted for the fact the element is in a default namespace in the XML. Your XSLT is looking for an element with no namespace.
You have declared the relevant namespace in your XSLT, so you just need to use the relevant prefix in the template match
<xsl:template match="cci:NotUsed2" />
For moving AutoTypesetInfo after NotUsed3 you should have a template that matches NotUsed3 where you can copy both the matched node, and the AutoTypesetInfo
<xsl:template match="cci:NotUsed3">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
<xsl:copy-of select="../cci:AutoTypesetInfo" />
</xsl:template>
You would also need a template to ensure the AutoTypesetInfo still doesn't get copied in its current position too
<xsl:template match="cci:AutoTypesetInfo" />
Try this XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cci="http://www.ccieurope.com/xmlns/CCIPlanner"
exclude-result-prefixes="msxsl cci">
<xsl:output indent="yes"/>
<xsl:template match="#* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- If element name match on NotUsed2, exclude from result -->
<xsl:template match="cci:NotUsed2" />
<xsl:template match="cci:NotUsed3">
<xsl:call-template name="identity" />
<xsl:copy-of select="../cci:AutoTypesetInfo" />
</xsl:template>
<xsl:template match="cci:AutoTypesetInfo" />
</xsl:stylesheet>
This does assume NotUsed3 is always present. If not, change the last template to this to ensure the original AutoTypesetInfo is not removed in this case.
<xsl:template match="cci:AutoTypesetInfo[../cci:NotUsed3]" />
Try below XSLT.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cci="http://www.ccieurope.com/xmlns/CCIPlanner"
exclude-result-prefixes="msxsl cci"
>
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- If element name match on NotUsed2, exclude from result -->
<xsl:template match="*[local-name()='NotUsed2']" />
</xsl:stylesheet>

Removing an XML element based on the value of other element

I have to achieve below.
if <m_control>/<initiator_id> is Dummy then the xml element, <note>/<reason> should be removed.Below is the hirarchy of the note element.
<o:m_content/o:application/o:product/o:client_specific_illustration/o:note>
Below is the sample xml:
<?xml version="1.0"?>
<message xmlns="http://www.origoservices.com" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<m_control>
<expected_response_type>synchronous</expected_response_type>
<initiator_id>Dummy</initiator_id>
<user_id>Dummy</user_id>
<responder_id>Responder</responder_id>
</m_control>
<m_content>
<b_control>
<message_version_number>3.7</message_version_number>
<submission_date>2014-04-14</submission_date>
</b_control>
<intermediary type="Test">
<rdr_basis_of_sale>
<advised_category>Independent</advised_category>
</rdr_basis_of_sale>
</intermediary>
<application>
<address id="ADPC2">
<postcode>AB24 3DB</postcode>
</address>
<address id="ADPC1">
<postcode>B14 7JG</postcode>
</address>
<personal_client id="PC1">
<title>Mr</title>
<forenames>Test</forenames>
<surname>FLtwelve</surname>
<sex>Male</sex>
<marital_status>Married</marital_status>
<date_of_birth>1950-10-16</date_of_birth>
<employment_contract>
<occupation code="AAB00021">Actuary</occupation>
<full_time_ind>No</full_time_ind>
</employment_contract>
<smoker_ind>No</smoker_ind>
<residential_status>In Own Home - With Someone Else</residential_status>
<home_address address_id="ADPC1"/>
<enhanced_underwriting>
<medical_conditions/>
</enhanced_underwriting>
<tpsdata>
<postcode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">test</postcode>
</tpsdata>
</personal_client>
<personal_client id="PC2">
<employment_contract>
<occupation code="WAB02558">Wig Maker</occupation>
<full_time_ind>Yes</full_time_ind>
</employment_contract>
<smoker_ind>Yes</smoker_ind>
<residential_status>In Own Home - Alone</residential_status>
<home_address address_id="ADPC2"/>
<enhanced_underwriting>
<medical_conditions/>
<lifestyle>
<height units="Centimetre">180</height>
<weight units="Kilogram">70</weight>
<waist units="Centimetre">81</waist>
<units_of_alcohol_per_week>1</units_of_alcohol_per_week>
<smoking_details>
<regular_smoker_ind>Yes</regular_smoker_ind>
<current_smoking>
<number_of_cigarettes_per_day>4</number_of_cigarettes_per_day>
<number_of_cigars_per_day>0</number_of_cigars_per_day>
<rolling_tobacco_per_week units="Gram">0</rolling_tobacco_per_week>
<pipe_tobacco_per_week units="Gram">0</pipe_tobacco_per_week>
<start_date>1985-09</start_date>
</current_smoking>
</smoking_details>
</lifestyle>
</enhanced_underwriting>
<tpsdata>
<postcode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AB24 3DB</postcode>
</tpsdata>
</personal_client>
<product type="Compulsory Purchase Annuity" product_code="CPA">
<open_market_option_ind>Yes</open_market_option_ind>
<annuity type="Non Protected Rights">
<annuitant sequence_number="1" personal_client_id="PC1"/>
<with_profit_ind>No</with_profit_ind>
<contribution legislation_applicable="Post 1997">
<amount currency="GBP">391586</amount>
<source_details>
<product_type>Occupational Scheme - Defined Contribution</product_type>
<product_provider_name>Other</product_provider_name>
<transfer_ind>No</transfer_ind>
</source_details>
<adviser_charges_applicable>
<adviser_charge_applicable adviser_charge_id="ac1"/>
</adviser_charges_applicable>
</contribution>
<payment_frequency>Annually</payment_frequency>
<payment_timing_code>In Advance</payment_timing_code>
<escalation>
<change_index>Level</change_index>
<lpi_lag_basis>Statutory</lpi_lag_basis>
<proportionate_escalation_ind>No</proportionate_escalation_ind>
</escalation>
<payment_period>
<start_basis>Specified Date</start_basis>
<start_date>2014-04-14</start_date>
</payment_period>
<guaranteed_period>
<years>5</years>
</guaranteed_period>
<commuted_ind>No</commuted_ind>
<with_proportion_ind>No</with_proportion_ind>
<reversionary_annuity type="Spouse" legislation_applicable="Post 1997">
<annuitant personal_client_id="PC2"/>
<number_of_dependants>1</number_of_dependants>
<fraction_of_original_payment>
<numerator>10</numerator>
<denominator>10</denominator>
</fraction_of_original_payment>
<payment_period>
<start_basis>Next Due Date</start_basis>
</payment_period>
<overlap_ind>No</overlap_ind>
<spouse_remarriage_cease_ind>Yes</spouse_remarriage_cease_ind>
</reversionary_annuity>
</annuity>
<adviser_charges>
<adviser_charge id="ac1">
<type>Adviser</type>
<amount currency="GBP">7831.72</amount>
<facilitated_from>Annuity In Payment</facilitated_from>
<facilitated_before_product_investment_ind>Yes</facilitated_before_product_investment_ind>
<payment_frequency>Single</payment_frequency>
<reason>Initial</reason>
</adviser_charge>
</adviser_charges>
<illustration_basis>
<annuity_calculation_required>Payment</annuity_calculation_required>
</illustration_basis>
<client_specific_illustration>
<expiry_date>2014-04-28</expiry_date>
<note>
<reason>reason for failure is specified over here</reason>
</note>
<pension_annuity type="Non Protected Rights">
<total_amount currency="GBP">18539.33</total_amount>
<reversionary_annuity>
<total_amount currency="GBP">18539.33</total_amount>
</reversionary_annuity>
</pension_annuity>
<adviser_charges>
<adviser_charge>
<adviser_charge_requested adviser_charge_id="ac1"/>
<type>Adviser</type>
<amount currency="GBP">7831.72</amount>
<facilitated_from>Annuity In Payment</facilitated_from>
<facilitated_before_product_investment_ind>Yes</facilitated_before_product_investment_ind>
<payment_frequency>Single</payment_frequency>
<reason>Initial</reason>
</adviser_charge>
</adviser_charges>
<tpsdata>
<guaranteed_quote>Yes</guaranteed_quote>
</tpsdata>
</client_specific_illustration>
</product>
<document_out type="Client Specific Illustration">
<print_requirements>
<distribution_method>Web Hosted</distribution_method>
<web_host_format>PDF</web_host_format>
</print_requirements>
</document_out>
</application>
</m_content>
</message>
Below is the xslt that I have tried, but I am not getting the expected output as the note/reason element is not getting removed.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:o="http://www.origoservices.com" xmlns:dp="http://www.datapower.com/extensions" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:date="http://exslt.org/dates-and-times" version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="fn date">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="o:m_content/o:application/o:product/o:client_specific_illustration/o:note[../../../../../o:m_control/o:initiator_id='TEX']">
</xsl:template>
</xsl:stylesheet>
Could anyone please let me know, where am I comiting mistake?
Regards.
Just have a variable to store the initiator_id. As below:
<xsl:variable name="test" select="o:message/o:m_control/o:initiator_id"/>
Then, test the note node
<xsl:template match="o:note[parent::o:client_specific_illustration]">
<xsl:choose>
<xsl:when test="$test='Dummy'"></xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
The complete stylesheet therefore is:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:o="http://www.origoservices.com" xmlns:dp="http://www.datapower.com/extensions"
xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:date="http://exslt.org/dates-and-times"
version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="fn date">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="test" select="o:message/o:m_control/o:initiator_id"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="o:note[parent::o:client_specific_illustration]">
<xsl:choose>
<xsl:when test="$test='Dummy'"></xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
as an alternative, you can just use
<xsl:template match="o:m_content[preceding-sibling::o:m_control/o:initiator_id='Dummy']/o:application/o:product/o:client_specific_illustration/o:note"/>

Modify node text within xsl copy-of

I have a xml document which looks like
<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Request xmlns="fst" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<AccountServer e-dtype="int">3</AccountServer>
</Header>
<Response>
<ResponseList e-dtype="list">
<Response>
<RequestId e-dtype="string">ServiceOrderGetRef</RequestId>
<RequestObjName e-dtype="string">ServiceOrder</RequestObjName>
<ServiceOrder>
<CreateDt e-dtype="dateTime">2014-03-01 00:00:00</CreateDt>
<CreateWho e-dtype="string">vc</CreateWho>
<WorkflowStartDt e-dtype="dateTime">2014-04-01 00:00:00</WorkflowStartDt>
</ServiceOrder>
</Response>
<Response>
<ComponentList e-dtype="list"/>
<Count e-dtype="int">0</Count>
<RequestId e-dtype="string">ComponentFindRef</RequestId>
<RequestObjName e-dtype="string">Component</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
<Response>
<Count e-dtype="int">0</Count>
<CustomerContractList e-dtype="list"/>
<RequestId e-dtype="string">CustomerContractRef</RequestId>
<RequestObjName e-dtype="string">CustomerContract</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
<Response>
<Count e-dtype="int">0</Count>
<ProductList e-dtype="list"/>
<RequestId e-dtype="string">ProductRef</RequestId>
<RequestObjName e-dtype="string">Product</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
<Response>
<Count e-dtype="int">0</Count>
<NrcList e-dtype="list"/>
<RequestId e-dtype="string">NrcFindRef</RequestId>
<RequestObjName e-dtype="string">Nrc</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
</ResponseList>
</Response>
</Request>
I am using copy-of function to copy node ServiceOrder within another xml document
I want to modify text of node WorkFlowStartDt and CreateDt and then do a copy-of. How can I do this?
My copied serviceorder node should look like this after modifing text. Below is the result xml
<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess>
<Fetch e-dtype="boolean">true</Fetch>
<Order>
<AccountInternalId e-dtype="int">12345</AccountInternalId>
<Key>
<OrderId e-dtype="numeric">12345678</OrderId>
</Key>
</Order>
<ServiceOrderList e-dtype="list">
<ServiceOrder xmlns="fst" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance">
<CreateDt e-dtype="dateTime">2014-03-02 00:00:00</CreateDt>
<CreateWho e-dtype="string">vc</CreateWho>
<WorkflowStartDt e-dtype="dateTime">2014-05-01 00:00:00</WorkflowStartDt>
</ServiceOrder>
</ServiceOrderList>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</RequestList>
</CustomerUdtRequest>
</Request>
Below is my xslt processor file
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess> <Order> <AccountInternalId e-dtype="int">
<xsl:value-of
select="/Request/Response/ResponseList/Response/ServiceOrder/AccountInternalId"/>
</AccountInternalId> <Key> <OrderId e-dtype="numeric"> <xsl:value-of select="/Request/Response/ResponseList/Response/ServiceOrder/OrderId"/>
</OrderId>
</Key>
</Order>
<ServiceOrderList e-dtype="list">
<xsl:copy-of select="/Request/Response/ResponseList/Response/ServiceOrder"/>
</ServiceOrderList>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</xsl:if>
</RequestList>
</CustomerUdtRequest>
</Request>
</xsl:template>
</xsl:stylesheet>
I want to modify text of node WorkFlowStartDt and CreateDt and then do
a copy-of.
That would be an unnecessary complication. You can modify nodes while you add them to the output tree.
Since you essentially want to copy everything "as is" except two nodes, it would be best to start with an identity transform template, then add an "exception" template for the two specific nodes that need modifying (one template for both, since the modification is identical).:
<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"/>
<!-- identity transformation -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CreateDt | WorkFlowStartDt">
<xsl:copy>
<xsl:value-of select="concat('**', ., '**')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Added:
In response to the edited question, try this stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="fst"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess>
<Order>
<AccountInternalId e-dtype="int">
<!-- THIS DOESN'T POINT TO ANY EXISTING NODE!! -->
<xsl:value-of select="ns:Request/ns:Response/ns:ResponseList/ns:Response/ns:ServiceOrder/ns:AccountInternalId"/>
</AccountInternalId>
<Key>
<OrderId e-dtype="numeric">
<!-- THIS DOESN'T POINT TO ANY EXISTING NODE!! -->
<xsl:value-of select="ns:Request/ns:Response/ns:ResponseList/ns:Response/ns:ServiceOrder/ns:OrderId"/>
</OrderId>
</Key>
</Order>
<xsl:apply-templates select="ns:Request/ns:Response/ns:ResponseList/ns:Response/ns:ServiceOrder"/>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</RequestList>
</CustomerUdtRequest>
</Request>
</xsl:template>
<xsl:template match="ns:ServiceOrder">
<xsl:copy>
<xsl:copy-of select="ns:CreateWho"/>
<xsl:apply-templates select="ns:CreateDt | ns:WorkflowStartDt"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns:CreateDt | ns:WorkflowStartDt">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:value-of select="concat('**', ., '**')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied to your input (minus the illegal opening comment), the following result is obtained:
<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess>
<Order>
<AccountInternalId e-dtype="int"/>
<Key>
<OrderId e-dtype="numeric"/>
</Key>
</Order>
<ServiceOrder xmlns="fst" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CreateWho e-dtype="string">vc</CreateWho>
<CreateDt e-dtype="dateTime">**2014-03-01 00:00:00**</CreateDt>
<WorkflowStartDt e-dtype="dateTime">**2014-04-01 00:00:00**</WorkflowStartDt>
</ServiceOrder>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</RequestList>
</CustomerUdtRequest>
</Request>

XSLT : Cummulative Sum (Conditional)

I need to do a conditional sum using XSLT. The sum of 'Oty' for each 'SKU' should be calculated only for providers listed within the 'Provider' node. In the provided example, the Qty for providerCode 4 should be skipped as its not in the 'Providers' list. I'm restricted to using XSLT 1.0.
I would appreciate any help. Thanks!
Here is the sample XML.
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Providers>
<ProviderCode>1</ProviderCode>
<ProviderCode>2</ProviderCode>
<ProviderCode>3</ProviderCode>
</Providers>
<SKU>
<SKU>XYZ</SKU>
<Description>XYZ Description</Description>
<Provider>
<ProviderCode>1</ProviderCode>
<Qty>100</Qty>
</Provider>
<Provider>
<ProviderCode>2</ProviderCode>
<Qty>67</Qty>
</Provider>
<Provider>
<ProviderCode>3</ProviderCode>
<Qty>74</Qty>
</Provider>
<Provider>
<ProviderCode>4</ProviderCode>
<Qty>62</Qty>
</Provider>
</SKU>
<SKU>
<SKU>ABC</SKU>
<Description>ABC Description</Description>
<Provider>
<ProviderCode>1</ProviderCode>
<Qty>20</Qty>
</Provider>
<Provider>
<ProviderCode>2</ProviderCode>
<Qty>77</Qty>
</Provider>
<Provider>
<ProviderCode>3</ProviderCode>
<Qty>42</Qty>
</Provider>
<Provider>
<ProviderCode>4</ProviderCode>
<Qty>631</Qty>
</Provider>
</SKU>
</Root>
Here is the required output.
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<SKU>
<SKU>XYZ</SKU>
<Qty>241</Qty>
</SKU>
<SKU>
<SKU>ABC</SKU>
<Qty>139</Qty>
</SKU>
</Root>
You can simply use sum on the nodes you want, either by comparing sum(Provider[ProviderCode = //Providers/ProviderCode]/Qty) or by using a key:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="prov" match="Providers/ProviderCode" use="."/>
<xsl:template match="Root">
<xsl:copy>
<xsl:apply-templates select="SKU"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Root/SKU">
<xsl:copy>
<xsl:copy-of select="SKU"/>
<Qty><xsl:value-of select="sum(Provider[key('prov', ProviderCode)]/Qty)"/></Qty>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

XSLT . call another template with xsl:param

I am new to xslt and trying to create one XSLT ,
I am calling aother template with passing param value to it
But somehow blank value is coming in param variable for destination template.
Here is the simplified sample xml file :
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<TCXML xmlns="http://www.tcxml.org/Schemas/TCXMLSchema">
<BOMWindow elemId="id62" revision_rule="id60" top_line="id2">
<GSIdentity elemId="id1" label="a00pC7EtM1CZ7D"/>
</BOMWindow>
<IMAN_Drawing elemId="id78" owning_site="id4" primary_object="#id21" secondary_object="#id25" user_data="">
<GSIdentity elemId="id50" label="R8D9sTvgBT4jNA"/>
</IMAN_Drawing>
<IMAN_Drawing elemId="id79" owning_site="#id4" primary_object="#id22" secondary_object="#id26" user_data="">
<GSIdentity elemId="id56" label="R8D9sTfVBT4jNA"/>
</IMAN_Drawing>
<IMAN_Drawing elemId="id80" owning_site="#id4" primary_object="#id20" secondary_object="#id24" user_data="">
<GSIdentity elemId="id44" label="R8A9sTu6BT4jNA"/>
</IMAN_Drawing>
<UGPART creation_date="2012-06-05T09:25:30Z" date_released="2012-06-05T09:25:33Z" ead_paragraph="" elemId="id117" format_used="PART" gov_classification="" object_name="Test" owning_organization="" >
<GSIdentity elemId="id21" label="RXM9sPifBT4jNA"/>
</UGPART>
<UGPART creation_date="2012-06-05T09:25:30Z" date_released="2012-06-05T09:25:33Z" ead_paragraph="" elemId="id117" format_used="PART" gov_classification="" object_name="Test2" owning_organization="" >
<GSIdentity elemId="id20" label="R3K9sPifBT4jNA"/>
</UGPART>
<UGPART creation_date="2012-06-05T09:25:30Z" date_released="2012-06-05T09:25:33Z" ead_paragraph="" elemId="id117" format_used="PART" gov_classification="" object_name="Test3" owning_organization="" >
<GSIdentity elemId="id22" label="xuO9sPifBT4jNA"/>
</UGPART>
In XML there are 3 IMAN_Drawing tags, and 3 UGPART tags
Here is my xslt for this
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:plm="http://www.tcxml.org/Schemas/TCXMLSchema" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/plm:TCXML/plm:IMAN_Drawing">
<xsl:copy>
<xsl:copy-of select="#*" />
<xsl:for-each select="/plm:TCXML/plm:IMAN_Drawing">
<xsl:variable name="currentSecObjectId" select="#secondary_object"/>
<xsl:variable name="RefSecObjectId" select="substring($currentSecObjectId,2)"/>
<xsl:variable name="currentPrimaryObjectId" select="/plm:TCXML/plm:IMAN_Drawing/#primary_object"/>
<xsl:variable name="RefPrimaryObjectId" select="substring($currentPrimaryObjectId,2)"/>
<xsl:call-template name="UGPart">
<xsl:with-param name="PriId" select="$RefPrimaryObjectId"/>
</xsl:call-template>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/plm:TCXML/plm:UGPART" name="UGPart">
<xsl:param name="PriId"/>
<xsl:copy>
<xsl:if test="#object_name="'Test'">
<xsl:attribute name="owning_organization">
<xsl:value-of select="$PriId"/>
</xsl:attribute>
</xsl:if>
<xsl:copy-of select="#*[not(name()='owning_organization')]" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
But the output is :
owning_organization=""
Expected Result is :
It should update owning_organization attribute which i am passing from template 1 with value = $RefPrimaryObjectId for UGPART when its #object_name="'Test'"
what is going wrong here ? why $RefPrimaryObjectId" value is not coming to second template.
You should really supply your expected output, otherwise it is really hard to understand what you want. I am making some-what of a guess as to your expected output based on your provided style-sheet.
I mean no disrespect and I am only trying to be helpful, but your style-sheet points to so many misconceptions, that rather than just picking my solution (provided below), you might be better off in the long term, by putting pens down and working through some published tutorials, or reading a book.
Any way ...
This style-sheet ...
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:plm="http://www.tcxml.org/Schemas/TCXMLSchema" >
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="plm:IMAN_Drawing">
<xsl:variable name="id" select="substring(#primary_object,2)" />
<xsl:copy>
<xsl:apply-templates select="#*"/>
</xsl:copy>
<xsl:for-each select="../plm:UGPART[plm:GSIdentity/#elemId=$id]" >
<xsl:copy>
<xsl:apply-templates select="#*[name()!='owning_organization' or ../#object_name!='Test']"/>
<xsl:if test="#object_name='Test'">
<xsl:attribute name="owning_organization"><xsl:value-of select="$id" /></xsl:attribute>
</xsl:if>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:template >
<xsl:template match="plm:UGPART" />
</xsl:stylesheet>
... when applied to your sample input, will produce output ...
<?xml version="1.0" encoding="utf-8"?>
<TCXML xmlns="http://www.tcxml.org/Schemas/TCXMLSchema">
<BOMWindow elemId="id62" revision_rule="#id60" top_line="#id2">
<GSIdentity elemId="id1" label="a00pC7EtM1CZ7D" />
</BOMWindow>
<IMAN_Drawing elemId="id78" owning_site="#id4" primary_object="#id21" secondary_object="#id25" user_data="" /><UGPART creation_date="2012-06-05T09:25:30Z" date_released="2012-06-05T09:25:33Z" ead_paragraph="" elemId="id117" format_used="PART" gov_classification="" object_name="Test" owning_organization="id21">
<GSIdentity elemId="id21" label="RXM9sPifBT4jNA" />
</UGPART>
<IMAN_Drawing elemId="id79" owning_site="#id4" primary_object="#id22" secondary_object="#id26" user_data="" /><UGPART creation_date="2012-06-05T09:25:30Z" date_released="2012-06-05T09:25:33Z" ead_paragraph="" elemId="id117" format_used="PART" gov_classification="" object_name="Test3" owning_organization="">
<GSIdentity elemId="id22" label="xuO9sPifBT4jNA" />
</UGPART>
<IMAN_Drawing elemId="id80" owning_site="#id4" primary_object="#id20" secondary_object="#id24" user_data="" /><UGPART creation_date="2012-06-05T09:25:30Z" date_released="2012-06-05T09:25:33Z" ead_paragraph="" elemId="id117" format_used="PART" gov_classification="" object_name="Test2" owning_organization="">
<GSIdentity elemId="id20" label="R3K9sPifBT4jNA" />
</UGPART>
</TCXML>
Let us know if I have misunderstood your expected output.