XSLT : Create one row for each element in output file - xslt
I have a requirement where I need to create a csv file using xslt 1.0/2.0.
In below Source XML - For each complex type element inside <Effective_Change>, In this case it is <Worker_Status> I need to create a row for each child element inside complex type element.
<?xml version="1.0" encoding="UTF-8"?>
<peci:Workers_Effective_Stack xmlns:peci="urn:com.w/peci">
<peci:Worker>
<peci:Summary>
<peci:Integration_Event>14d964101fdb0156e164341b45548d01</peci:Integration_Event>
<peci:Integration_Sent_On>2018-05-10T08:41:39.375-07:00</peci:Integration_Sent_On>
<peci:Payroll_Company_Name>West Brooke - Biweekly: B</peci:Payroll_Company_Name>
<peci:Pay_Group_Country>US</peci:Pay_Group_Country>
</peci:Summary>
<peci:Worker>
<peci:Worker_Summary>
<peci:WID>rd</peci:WID>
<peci:Employee_ID>33333</peci:Employee_ID>
<peci:Name>Test 1</peci:Name>
</peci:Worker_Summary>
<peci:Effective_Change peci:Sequence="0">
<peci:Derived_Event_Code>DTA</peci:Derived_Event_Code>
<peci:Effective_Moment>2018-05-10T08:29:21.235-07:00</peci:Effective_Moment>
<peci:Entry_Moment>2018-05-10T08:29:21.235-07:00</peci:Entry_Moment>
<peci:Worker_Status>
<peci:Status>Active</peci:Status>
<peci:Active>1</peci:Active>
<peci:Active_Status_Date>2018-01-08-08:00</peci:Active_Status_Date>
<peci:Terminated>0</peci:Terminated>
<peci:Hire_Date>2018-01-08-08:00</peci:Hire_Date>
<peci:Original_Hire_Date>2018-01-08-08:00</peci:Original_Hire_Date>
<peci:Is_Rehire>0</peci:Is_Rehire>
<peci:Continuous_Service_Date>2018-01-08-08:00</peci:Continuous_Service_Date>
<peci:First_Day_of_Work>2018-01-08-08:00</peci:First_Day_of_Work>
<peci:Seniority_Date>2018-01-08-08:00</peci:Seniority_Date>
</peci:Worker_Status>
</peci:Effective_Change>
<peci:Effective_Change peci:Sequence="1">
<peci:Derived_Event_Code>DTA</peci:Derived_Event_Code>
<peci:Effective_Moment>2018-05-10T08:31:27.880-07:00</peci:Effective_Moment>
<peci:Entry_Moment>2018-05-10T08:31:27.880-07:00</peci:Entry_Moment>
<peci:Worker_Status>
<peci:Status>Active</peci:Status>
<peci:Active>1</peci:Active>
<peci:Active_Status_Date>2018-01-08-08:00</peci:Active_Status_Date>
<peci:Terminated>0</peci:Terminated>
<peci:Hire_Date>2018-01-08-08:00</peci:Hire_Date>
<peci:Original_Hire_Date>2018-01-08-08:00</peci:Original_Hire_Date>
<peci:Is_Rehire>0</peci:Is_Rehire>
<peci:Continuous_Service_Date>2018-01-08-08:00</peci:Continuous_Service_Date>
<peci:First_Day_of_Work>2018-01-08-08:00</peci:First_Day_of_Work>
<peci:Seniority_Date>2018-01-08-08:00</peci:Seniority_Date>
</peci:Worker_Status>
</peci:Worker>
</peci:Workers_Effective_Stack>
<?xml version='1.0' encoding='UTF-8'?>
<peci:Workers_Effective_Stack xmlns:peci="urn:com.workday/peci">
<peci:Summary>
<peci:Payroll_Company_ID>Test Company</peci:Payroll_Company_ID>
<peci:Payroll_Company_Name>Test Company</peci:Payroll_Company_Name>
<peci:Pay_Group_ID>Monthly</peci:Pay_Group_ID>
<peci:Pay_Group_Name>Test</peci:Pay_Group_Name>
<peci:Pay_Group_Country>SE</peci:Pay_Group_Country>
<peci:Pay_Group_Code>3</peci:Pay_Group_Code>
<peci:Pay_Period_Start>2017-03-01-03.34</peci:Pay_Period_Start>
<peci:Pay_Period_End>2017-03-30-03.34</peci:Pay_Period_End>
<peci:Updated_From>2017-03-10T07:56:16.000-03.34</peci:Updated_From>
<peci:Updated_To>2017-03-19T09:06:13.769-03.34</peci:Updated_To>
<peci:Effective_From>2017-03-01-03.34</peci:Effective_From>
<peci:Effective_To>2017-03-30-03.34</peci:Effective_To>
<peci:Change_Detection>Test</peci:Change_Detection>
<peci:First_Primary_Run_of_Pay_Period>0</peci:First_Primary_Run_of_Pay_Period>
<peci:Ad_Hoc_Run>1</peci:Ad_Hoc_Run>
<peci:Full_Snapshot>0</peci:Full_Snapshot>
<peci:Worker_Count>1</peci:Worker_Count>
<peci:Version>1</peci:Version>
</peci:Summary>
<peci:Worker>
<peci:Worker_Summary>
<peci:WID>2232</peci:WID>
<peci:Employee_ID>1141</peci:Employee_ID>
<peci:Name>Andrew D Johnson</peci:Name>
</peci:Worker_Summary>
<peci:Effective_Change peci:Sequence="0">
<peci:Derived_Event_Code>HIR</peci:Derived_Event_Code>
<peci:Effective_Moment>2017-03-10T00:00:00.000-03.34</peci:Effective_Moment>
<peci:Entry_Moment>2017-03-11T04:51:00.632-03.34</peci:Entry_Moment>
<peci:Worker_Status peci:isUpdated="1">
<peci:Status peci:isAdded="1">Active</peci:Status>
<peci:Active peci:priorValue="0">1</peci:Active>
<peci:Active_Status_Date peci:isAdded="1">2017-03-10-03.34</peci:Active_Status_Date>
<peci:Terminated>0</peci:Terminated>
<peci:Hire_Date peci:isAdded="1">2017-03-10-03.34</peci:Hire_Date>
<peci:Original_Hire_Date peci:isAdded="1">2017-03-10-03.34</peci:Original_Hire_Date>
<peci:Hire_Rescinded>0</peci:Hire_Rescinded>
<peci:Is_Rehire>0</peci:Is_Rehire>
<peci:End_Employment_Date peci:isAdded="1">2021-05-31-03.34</peci:End_Employment_Date>
</peci:Worker_Status>
<peci:Personal peci:isUpdated="1">
<peci:Legal_Name peci:isAdded="1">
<peci:First_Name>Andrew</peci:First_Name>
<peci:Middle_Name>D</peci:Middle_Name>
<peci:Last_Name>Johnson</peci:Last_Name>
</peci:Legal_Name>
<peci:Workday_Account peci:isAdded="1">1141</peci:Workday_Account>
</peci:Personal>
<peci:Person_Communication peci:isUpdated="1">
<peci:Email peci:isAdded="1">
<peci:Usage_Type>HOME</peci:Usage_Type>
<peci:Email_Address>adjohnson#gmail.com</peci:Email_Address>
</peci:Email>
</peci:Person_Communication>
<peci:Person_Identification peci:isUpdated="1">
<peci:National_Identifier peci:isAdded="1">
<peci:National_ID>2037203020</peci:National_ID>
<peci:National_ID_Type>DL</peci:National_ID_Type>
</peci:National_Identifier>
</peci:Person_Identification>
<peci:Position peci:isAdded="1">
<peci:Worker_Type>Fixed_Term</peci:Worker_Type>
<peci:Position_Time_Type>Full_time</peci:Position_Time_Type>
<peci:Job_Exempt>0</peci:Job_Exempt>
<peci:Scheduled_Weekly_Hours>40</peci:Scheduled_Weekly_Hours>
<peci:Default_Weekly_Hours>40</peci:Default_Weekly_Hours>
<peci:Pay_Rate_Type>Salaried</peci:Pay_Rate_Type>
<peci:Job_Classification>
<peci:Job_Classification_Group>FT</peci:Job_Classification_Group>
<peci:Job_Classification_ID>232</peci:Job_Classification_ID>
</peci:Job_Classification>
<peci:Management_Level>AL1</peci:Management_Level>
<peci:Job_Category>TA</peci:Job_Category>
<peci:Business_Site>
<peci:Location_ID>CA_001</peci:Location_ID>
</peci:Business_Site>
<peci:Supervisor>
<peci:ID>1139</peci:ID>
<peci:Name>David Brown</peci:Name>
</peci:Supervisor>
<peci:Probation_Start_Date>2017-03-10-03.34</peci:Probation_Start_Date>
<peci:Probation_End_Date>2020-07-10-03.34</peci:Probation_End_Date>
</peci:Position>
<peci:Compensation peci:isAdded="1">
<peci:Compensation_Summary_in_Pay_Group_Frequency>
<peci:Total_Base_Pay>34000</peci:Total_Base_Pay>
<peci:Frequency>Yearly</peci:Frequency>
</peci:Compensation_Summary_in_Pay_Group_Frequency>
</peci:Compensation>
<peci:Compensation_Plans peci:isAdded="1">
<peci:Salary_and_Hourly_Plan>
<peci:Compensation_Plan>Base_Salary</peci:Compensation_Plan>
<peci:Amount>34000</peci:Amount>
<peci:Apply_FTE>1</peci:Apply_FTE>
<peci:Frequency>Yearly</peci:Frequency>
<peci:Start_Date>2017-03-10-03.34</peci:Start_Date>
</peci:Salary_and_Hourly_Plan>
</peci:Compensation_Plans>
<peci:Employee_Contract peci:isAdded="1">
<peci:Start_Date>2017-03-10-03.34</peci:Start_Date>
<peci:Contract_Status>Closed</peci:Contract_Status>
</peci:Employee_Contract>
<peci:Collective_Agreement peci:isAdded="1">
<peci:Collective_Agreement>No</peci:Collective_Agreement>
<peci:Collective_Agreement_Factor>
<peci:Factor>level</peci:Factor>
</peci:Collective_Agreement_Factor>
<peci:Collective_Agreement_Factor>
<peci:Factor>level</peci:Factor>
</peci:Collective_Agreement_Factor>
</peci:Collective_Agreement>
<peci:Additional_Information>
<peci:WorkerID>2232</peci:WorkerID>
</peci:Additional_Information>
</peci:Effective_Change>
<peci:Effective_Change peci:Sequence="1">
<peci:Derived_Event_Code>DTA</peci:Derived_Event_Code>
<peci:Effective_Moment>2017-03-11T00:00:00.000-03.34</peci:Effective_Moment>
<peci:Entry_Moment>2017-03-11T04:47:25.190-03.34</peci:Entry_Moment>
<peci:Person_Communication peci:isUpdated="1">
<peci:Address peci:isAdded="1">
<peci:Usage_Type>HOME</peci:Usage_Type>
<peci:Address_Line_1>Address_Line_1</peci:Address_Line_1>
<peci:City>City</peci:City>
<peci:Postal_Code>32323</peci:Postal_Code>
<peci:Country>US</peci:Country>
</peci:Address>
<peci:Email>
<peci:Usage_Type>HOME</peci:Usage_Type>
<peci:Email_Address>adjohnson#gmail.com</peci:Email_Address>
</peci:Email>
</peci:Person_Communication>
</peci:Effective_Change>
</peci:Worker>
</peci:Workers_Effective_Stack>
Outfile should have below format.
Derived_Event_Code,Effective_Moment,xml_element_name,xml_element_value
**Example output CSV file:**
DTA,2018-05-10,Status,Active
DTA,2018-05-10,Active,1
DTA,2018-05-10,Active_Status_Date,2018-01-08-08:00
DTA,2018-05-10,Terminated,0
DTA,2018-05-10,Hire_Date,2018-01-08-08:00
DTA,2018-05-10,Original_Hire_Date,2018-01-08-08:00
DTA,2018-05-10,Is_Rehire,0
DTA,2018-05-10,Continuous_Service_Date,0
DTA,2018-05-10,First_Day_of_Work,2018-01-08-08:00
DTA,2018-05-10,Seniority_Date,2018-01-08-08:00
DTA,2018-05-10,Status,Active
DTA,2018-05-10,Active,1
DTA,2018-05-10,Active_Status_Date,2018-01-08-08:00
DTA,2018-05-10,Terminated,0
DTA,2018-05-10,Hire_Date,2018-01-08-08:00
DTA,2018-05-10,Original_Hire_Date,2018-01-08-08:00
DTA,2018-05-10,Is_Rehire,0
DTA,2018-05-10,Continuous_Service_Date,0
DTA,2018-05-10,First_Day_of_Work,2018-01-08-08:00
DTA,2018-05-10,Seniority_Date,2018-01-08-08:00
Can someone suggest me how to achieve using xslt ?
Consider the following example:
XML
<peci:Workers_Effective_Stack xmlns:peci="urn:com.workday/peci">
<peci:Summary>
<peci:Payroll_Company_ID>Test Company</peci:Payroll_Company_ID>
<peci:Payroll_Company_Name>Test Company</peci:Payroll_Company_Name>
<peci:Pay_Group_ID>Monthly</peci:Pay_Group_ID>
<peci:Pay_Group_Name>Test</peci:Pay_Group_Name>
<peci:Pay_Group_Country>SE</peci:Pay_Group_Country>
<peci:Pay_Group_Code>3</peci:Pay_Group_Code>
<peci:Pay_Period_Start>2017-03-01-03.34</peci:Pay_Period_Start>
<peci:Pay_Period_End>2017-03-30-03.34</peci:Pay_Period_End>
<peci:Updated_From>2017-03-10T07:56:16.000-03.34</peci:Updated_From>
<peci:Updated_To>2017-03-19T09:06:13.769-03.34</peci:Updated_To>
<peci:Effective_From>2017-03-01-03.34</peci:Effective_From>
<peci:Effective_To>2017-03-30-03.34</peci:Effective_To>
<peci:Change_Detection>Test</peci:Change_Detection>
<peci:First_Primary_Run_of_Pay_Period>0</peci:First_Primary_Run_of_Pay_Period>
<peci:Ad_Hoc_Run>1</peci:Ad_Hoc_Run>
<peci:Full_Snapshot>0</peci:Full_Snapshot>
<peci:Worker_Count>1</peci:Worker_Count>
<peci:Version>1</peci:Version>
</peci:Summary>
<peci:Worker>
<peci:Worker_Summary>
<peci:WID>2232</peci:WID>
<peci:Employee_ID>1141</peci:Employee_ID>
<peci:Name>Andrew D Johnson</peci:Name>
</peci:Worker_Summary>
<peci:Effective_Change peci:Sequence="0">
<peci:Derived_Event_Code>HIR</peci:Derived_Event_Code>
<peci:Effective_Moment>2017-03-10T00:00:00.000-03.34</peci:Effective_Moment>
<peci:Entry_Moment>2017-03-11T04:51:00.632-03.34</peci:Entry_Moment>
<peci:Worker_Status peci:isUpdated="1">
<peci:Status peci:isAdded="1">Active</peci:Status>
<peci:Active peci:priorValue="0">1</peci:Active>
<peci:Active_Status_Date peci:isAdded="1">2017-03-10-03.34</peci:Active_Status_Date>
<peci:Terminated>0</peci:Terminated>
<peci:Hire_Date peci:isAdded="1">2017-03-10-03.34</peci:Hire_Date>
<peci:Original_Hire_Date peci:isAdded="1">2017-03-10-03.34</peci:Original_Hire_Date>
<peci:Hire_Rescinded>0</peci:Hire_Rescinded>
<peci:Is_Rehire>0</peci:Is_Rehire>
<peci:End_Employment_Date peci:isAdded="1">2021-05-31-03.34</peci:End_Employment_Date>
</peci:Worker_Status>
<peci:Personal peci:isUpdated="1">
<peci:Legal_Name peci:isAdded="1">
<peci:First_Name>Andrew</peci:First_Name>
<peci:Middle_Name>D</peci:Middle_Name>
<peci:Last_Name>Johnson</peci:Last_Name>
</peci:Legal_Name>
<peci:Workday_Account peci:isAdded="1">1141</peci:Workday_Account>
</peci:Personal>
<peci:Person_Communication peci:isUpdated="1">
<peci:Email peci:isAdded="1">
<peci:Usage_Type>HOME</peci:Usage_Type>
<peci:Email_Address>adjohnson#gmail.com</peci:Email_Address>
</peci:Email>
</peci:Person_Communication>
<peci:Person_Identification peci:isUpdated="1">
<peci:National_Identifier peci:isAdded="1">
<peci:National_ID>2037203020</peci:National_ID>
<peci:National_ID_Type>DL</peci:National_ID_Type>
</peci:National_Identifier>
</peci:Person_Identification>
<peci:Position peci:isAdded="1">
<peci:Worker_Type>Fixed_Term</peci:Worker_Type>
<peci:Position_Time_Type>Full_time</peci:Position_Time_Type>
<peci:Job_Exempt>0</peci:Job_Exempt>
<peci:Scheduled_Weekly_Hours>40</peci:Scheduled_Weekly_Hours>
<peci:Default_Weekly_Hours>40</peci:Default_Weekly_Hours>
<peci:Pay_Rate_Type>Salaried</peci:Pay_Rate_Type>
<peci:Job_Classification>
<peci:Job_Classification_Group>FT</peci:Job_Classification_Group>
<peci:Job_Classification_ID>232</peci:Job_Classification_ID>
</peci:Job_Classification>
<peci:Management_Level>AL1</peci:Management_Level>
<peci:Job_Category>TA</peci:Job_Category>
<peci:Business_Site>
<peci:Location_ID>CA_001</peci:Location_ID>
</peci:Business_Site>
<peci:Supervisor>
<peci:ID>1139</peci:ID>
<peci:Name>David Brown</peci:Name>
</peci:Supervisor>
<peci:Probation_Start_Date>2017-03-10-03.34</peci:Probation_Start_Date>
<peci:Probation_End_Date>2020-07-10-03.34</peci:Probation_End_Date>
</peci:Position>
<peci:Compensation peci:isAdded="1">
<peci:Compensation_Summary_in_Pay_Group_Frequency>
<peci:Total_Base_Pay>34000</peci:Total_Base_Pay>
<peci:Frequency>Yearly</peci:Frequency>
</peci:Compensation_Summary_in_Pay_Group_Frequency>
</peci:Compensation>
<peci:Compensation_Plans peci:isAdded="1">
<peci:Salary_and_Hourly_Plan>
<peci:Compensation_Plan>Base_Salary</peci:Compensation_Plan>
<peci:Amount>34000</peci:Amount>
<peci:Apply_FTE>1</peci:Apply_FTE>
<peci:Frequency>Yearly</peci:Frequency>
<peci:Start_Date>2017-03-10-03.34</peci:Start_Date>
</peci:Salary_and_Hourly_Plan>
</peci:Compensation_Plans>
<peci:Employee_Contract peci:isAdded="1">
<peci:Start_Date>2017-03-10-03.34</peci:Start_Date>
<peci:Contract_Status>Closed</peci:Contract_Status>
</peci:Employee_Contract>
<peci:Collective_Agreement peci:isAdded="1">
<peci:Collective_Agreement>No</peci:Collective_Agreement>
<peci:Collective_Agreement_Factor>
<peci:Factor>level</peci:Factor>
</peci:Collective_Agreement_Factor>
<peci:Collective_Agreement_Factor>
<peci:Factor>level</peci:Factor>
</peci:Collective_Agreement_Factor>
</peci:Collective_Agreement>
<peci:Additional_Information>
<peci:WorkerID>2232</peci:WorkerID>
</peci:Additional_Information>
</peci:Effective_Change>
<peci:Effective_Change peci:Sequence="1">
<peci:Derived_Event_Code>DTA</peci:Derived_Event_Code>
<peci:Effective_Moment>2017-03-11T00:00:00.000-03.34</peci:Effective_Moment>
<peci:Entry_Moment>2017-03-11T04:47:25.190-03.34</peci:Entry_Moment>
<peci:Person_Communication peci:isUpdated="1">
<peci:Address peci:isAdded="1">
<peci:Usage_Type>HOME</peci:Usage_Type>
<peci:Address_Line_1>Address_Line_1</peci:Address_Line_1>
<peci:City>City</peci:City>
<peci:Postal_Code>32323</peci:Postal_Code>
<peci:Country>US</peci:Country>
</peci:Address>
<peci:Email>
<peci:Usage_Type>HOME</peci:Usage_Type>
<peci:Email_Address>adjohnson#gmail.com</peci:Email_Address>
</peci:Email>
</peci:Person_Communication>
</peci:Effective_Change>
</peci:Worker>
</peci:Workers_Effective_Stack>
XSLT 1.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:peci="urn:com.workday/peci">
<xsl:output method="text"/>
<xsl:template match="/peci:Workers_Effective_Stack">
<xsl:for-each select="peci:Worker/peci:Effective_Change">
<xsl:variable name="common-data">
<xsl:value-of select="peci:Derived_Event_Code"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="peci:Effective_Moment"/>
<xsl:text>,</xsl:text>
</xsl:variable>
<!-- for every leaf descendant -->
<xsl:for-each select="*//*[not(*)]">
<xsl:copy-of select="$common-data"/>
<xsl:value-of select="local-name()"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Result
HIR,2017-03-10T00:00:00.000-03.34,Status,Active
HIR,2017-03-10T00:00:00.000-03.34,Active,1
HIR,2017-03-10T00:00:00.000-03.34,Active_Status_Date,2017-03-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Terminated,0
HIR,2017-03-10T00:00:00.000-03.34,Hire_Date,2017-03-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Original_Hire_Date,2017-03-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Hire_Rescinded,0
HIR,2017-03-10T00:00:00.000-03.34,Is_Rehire,0
HIR,2017-03-10T00:00:00.000-03.34,End_Employment_Date,2021-05-31-03.34
HIR,2017-03-10T00:00:00.000-03.34,First_Name,Andrew
HIR,2017-03-10T00:00:00.000-03.34,Middle_Name,D
HIR,2017-03-10T00:00:00.000-03.34,Last_Name,Johnson
HIR,2017-03-10T00:00:00.000-03.34,Workday_Account,1141
HIR,2017-03-10T00:00:00.000-03.34,Usage_Type,HOME
HIR,2017-03-10T00:00:00.000-03.34,Email_Address,adjohnson#gmail.com
HIR,2017-03-10T00:00:00.000-03.34,National_ID,2037203020
HIR,2017-03-10T00:00:00.000-03.34,National_ID_Type,DL
HIR,2017-03-10T00:00:00.000-03.34,Worker_Type,Fixed_Term
HIR,2017-03-10T00:00:00.000-03.34,Position_Time_Type,Full_time
HIR,2017-03-10T00:00:00.000-03.34,Job_Exempt,0
HIR,2017-03-10T00:00:00.000-03.34,Scheduled_Weekly_Hours,40
HIR,2017-03-10T00:00:00.000-03.34,Default_Weekly_Hours,40
HIR,2017-03-10T00:00:00.000-03.34,Pay_Rate_Type,Salaried
HIR,2017-03-10T00:00:00.000-03.34,Job_Classification_Group,FT
HIR,2017-03-10T00:00:00.000-03.34,Job_Classification_ID,232
HIR,2017-03-10T00:00:00.000-03.34,Management_Level,AL1
HIR,2017-03-10T00:00:00.000-03.34,Job_Category,TA
HIR,2017-03-10T00:00:00.000-03.34,Location_ID,CA_001
HIR,2017-03-10T00:00:00.000-03.34,ID,1139
HIR,2017-03-10T00:00:00.000-03.34,Name,David Brown
HIR,2017-03-10T00:00:00.000-03.34,Probation_Start_Date,2017-03-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Probation_End_Date,2020-07-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Total_Base_Pay,34000
HIR,2017-03-10T00:00:00.000-03.34,Frequency,Yearly
HIR,2017-03-10T00:00:00.000-03.34,Compensation_Plan,Base_Salary
HIR,2017-03-10T00:00:00.000-03.34,Amount,34000
HIR,2017-03-10T00:00:00.000-03.34,Apply_FTE,1
HIR,2017-03-10T00:00:00.000-03.34,Frequency,Yearly
HIR,2017-03-10T00:00:00.000-03.34,Start_Date,2017-03-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Start_Date,2017-03-10-03.34
HIR,2017-03-10T00:00:00.000-03.34,Contract_Status,Closed
HIR,2017-03-10T00:00:00.000-03.34,Collective_Agreement,No
HIR,2017-03-10T00:00:00.000-03.34,Factor,level
HIR,2017-03-10T00:00:00.000-03.34,Factor,level
HIR,2017-03-10T00:00:00.000-03.34,WorkerID,2232
DTA,2017-03-11T00:00:00.000-03.34,Usage_Type,HOME
DTA,2017-03-11T00:00:00.000-03.34,Address_Line_1,Address_Line_1
DTA,2017-03-11T00:00:00.000-03.34,City,City
DTA,2017-03-11T00:00:00.000-03.34,Postal_Code,32323
DTA,2017-03-11T00:00:00.000-03.34,Country,US
DTA,2017-03-11T00:00:00.000-03.34,Usage_Type,HOME
DTA,2017-03-11T00:00:00.000-03.34,Email_Address,adjohnson#gmail.com
Related
Xpath3 expression or XSLT code to fetch all node names with particular attributes in order that they appear
I have the below XML structure and I need to retrieve all node names that have attributes isAdded or isUpdated = 1. <?xml version="1.0" encoding="utf-8"?> <peci:Effective_Change xmlns:peci="urn:com.workday/peci" peci:Sequence="0"> <peci:Derived_Event_Code>DTA</peci:Derived_Event_Code> <peci:Effective_Moment>01.11.2020</peci:Effective_Moment> <peci:Entry_Moment>23.11.2020</peci:Entry_Moment> <peci:Worker_Status> <peci:Status>Active</peci:Status> <peci:Active>1</peci:Active> </peci:Worker_Status> <peci:Position peci:isAdded="1"> <peci:Position_ID>P0000</peci:Position_ID> <peci:Business_Site> <peci:Location_ID>US</peci:Location_ID> </peci:Business_Site> <peci:Position_End_Date peci:isAdded="1">01.11.2020</peci:Position_End_Date> </peci:Position> <peci:Position peci:isUpdated="1"> <peci:Position_ID>P0000</peci:Position_ID> <peci:Business_Site> <peci:Location_ID>US</peci:Location_ID> </peci:Business_Site> <peci:Position_End_Date peci:isAdded="1">01.11.2020</peci:Position_End_Date> </peci:Position> <peci:Compensation peci:isUpdated="1"> <peci:Position_ID>P0000</peci:Position_ID> <peci:Primary_Job>1</peci:Primary_Job> <peci:Business_Site> <peci:Country>US</peci:Country> </peci:Business_Site> </peci:Compensation> </peci:Effective_Change> The output I am looking for is a list like below Positon isAdded Positon isUpdated Compensation isUpdated Can someone help?
Seems very straightforward, something like: /*/*[#peci:isAdded = 1 or #peci:isUpdated = 1]/(local-name() || ' ' || local-name(#*)]
XSLT 1.0 Help Conditional Looping
I have a requirement and below is the case , If Input Message Record is null then i have to populate with a empty value in OutPut Message If Input Message Record is not null then i have to loop Below is the two different Input messages : Case one Input : Record is Null <ns0:Root xmlns:ns0="http://Correlation.Input1"> <company>abc</company> <Token>1243</Token> </ns0:Root> Case two Input : Multiple Record <ns0:Root xmlns:ns0="http://Correlation.Input1"> <company>abc</company> <Token>1243</Token> <Record> <Name>John</Name> </Record> <Record> <Name>Larry</Name> </Record> </ns0:Root> Desire OutPut For Case 1 : <ns0:Root xmlns:ns0="http://Correlation.Output"> <Company>abc</Company> <Token>1243</Token> <Record> <Name>Default</Name> </Record> </ns0:Root> Desire OutPut For Case 2 : <ns0:Root xmlns:ns0="http://Correlation.Output"> <Company>abc</Company> <Token>1243</Token> <Record> <Name>John</Name> </Record> <Record> <Name>Larry</Name> </Record> </ns0:Root> XSLT I have wrote : <?xml version="1.0" encoding="UTF-16"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0 userCSharp" version="1.0" xmlns:s0="http://Correlation.Input1" xmlns:ns0="http://Correlation.Output" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp"> <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> <xsl:template match="/"> <xsl:apply-templates select="/s0:Root" /> </xsl:template> <xsl:template match="/s0:Root"> <xsl:variable name="var:v1" select="count(/s0:Root/Record)" /> <xsl:variable name="var:v2" select="userCSharp:LogicalEq(string($var:v1) , "0")" /> <xsl:variable name="var:v4" select="userCSharp:LogicalNot(string($var:v2))" /> <ns0:Root> <Company> <xsl:value-of select="company/text()" /> </Company> <xsl:if test="Token"> <Token> <xsl:value-of select="Token/text()" /> </Token> </xsl:if> <Record> <xsl:if test="string($var:v2)='true'"> <xsl:variable name="var:v3" select=""Default"" /> <Name> <xsl:value-of select="$var:v3" /> </Name> </xsl:if> <xsl:if test="string($var:v4)='true'"> <xsl:variable name="var:v5" select=""fgfdg"" /> <Name> <xsl:value-of select="$var:v5" /> </Name> </xsl:if> <xsl:if test="string($var:v4)='true'"> <xsl:variable name="var:v6" select=""fgfdg"" /> <xsl:value-of select="$var:v6" /> </xsl:if> </Record> </ns0:Root> </xsl:template> <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[ public bool LogicalEq(string val1, string val2) { bool ret = false; double d1 = 0; double d2 = 0; if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2)) { ret = d1 == d2; } else { ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0; } return ret; } public bool LogicalNot(string val) { return !ValToBool(val); } public bool IsNumeric(string val) { if (val == null) { return false; } double d = 0; return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d); } public bool IsNumeric(string val, ref double d) { if (val == null) { return false; } return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d); } public bool ValToBool(string val) { if (val != null) { if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0) { return true; } if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0) { return false; } val = val.Trim(); if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0) { return true; } if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0) { return false; } double d = 0; if (IsNumeric(val, ref d)) { return (d > 0); } } return false; } ]]></msxsl:script> </xsl:stylesheet>
Couldn't you do simply: XSLT 1.0 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://Correlation.Input1" exclude-result-prefixes="ns0"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="ns0:Root"> <ns0:Root xmlns:ns0="http://Correlation.Output"> <xsl:apply-templates/> <xsl:if test="not(Record)"> <Record> <Name>Default</Name> </Record> </xsl:if> </ns0:Root> </xsl:template> <xsl:template match="*"> <xsl:element name="{local-name()}" > <xsl:apply-templates/> </xsl:element> </xsl:template> </xsl:stylesheet>
Give this a try. Step through it in you debugger. Let me know about questions. Add the formatting that you want. <xsl:template match="ns0:Root "> <xsl:copy> <xsl:apply-templates select="node()"/> <xsl:if test="not(Record[1])"> <xsl:element name="Record"> <xsl:element name="Name"> <xsl:value-of select="'Default'"/> </xsl:element> </xsl:element> </xsl:if> </xsl:copy> </xsl:template> <xsl:template match="Record"> <xsl:copy> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <xsl:template match="Name"> <xsl:copy> <xsl:value-of select="."/> </xsl:copy> </xsl:template> <xsl:template match="company"> <xsl:copy> <xsl:value-of select="."/> </xsl:copy> </xsl:template> <xsl:template match="Token"> <xsl:copy> <xsl:value-of select="."/> </xsl:copy> </xsl:template> <xsl:template match="node()|#*"> <xsl:apply-templates select="node()|#*"/> </xsl:template>
Overwrite an existing text file c++
This is how my Save As works - it is copying the current file's lines until it reaches the first figure and then I use my print methods to print the figure's info and then close the tag. std::ofstream newFile(filePath1_fixed, std::ios::app); std::fstream openedFile(filePath); std::string line1; while (std::getline(openedFile, line1)) { if (line1.find("<rect") != std::string::npos || line1.find("<circle") != std::string::npos || line1.find("<line") != std::string::npos) break; newFile << line1 << std::endl; } figc.printToFile(newFile); newFile << "</svg>\n"; My question is how to save the changes to the current file? I tried something like this: std::ifstream openedFile(filePath); std::ofstream newFile(filePath, std::ios::app); std::string line1; std::string info_beg[100]; int t = 0; while (std::getline(openedFile, line1)) { std::cout << "HELLYEAH"; if (line1.find("<rect") != std::string::npos || line1.find("<circle") != std::string::npos || line1.find("<line") != std::string::npos) break; info_beg[t++] = line1; } for (int i = 0; i < t; i++) newFile << info_beg[i] << std::endl; figc.printToFile(newFile); newFile << "</svg>\n"; This is the nearest I've gone. I get this: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example rect01 - rectangle with sharp corners</desc> <!-- Show outline of canvas using 'rect' element --> <rect x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2" /> <line x1="20" y1="100" x2="100" y2="20" stroke="red" stroke-width="2" /> <rect x="20" y="30" width="40" height="50" fill="red" stroke="red" stroke-width="1" /> <rect x="10" y="20" width="30" height="40" fill="red" stroke="blue" stroke-width="1" /> <line x1="100" y1="200" x2="300" y2="400" stroke="red" stroke-width="2" /> <circle cx="10" cy="20" r="30" fill="red" stroke="blue" stroke-width="2" /> </svg> <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example rect01 - rectangle with sharp corners</desc> <!-- Show outline of canvas using 'rect' element --> <rect x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2" /> <line x1="20" y1="100" x2="100" y2="20" stroke="red" stroke-width="2" /> <rect x="20" y="30" width="40" height="50" fill="red" stroke="red" stroke-width="1" /> <rect x="10" y="20" width="30" height="40" fill="red" stroke="blue" stroke-width="1" /> <line x1="100" y1="200" x2="300" y2="400" stroke="red" stroke-width="2" /> <circle cx="10" cy="20" r="30" fill="red" stroke="blue" stroke-width="2" /> <rect x="10" y="20" width="30" height="40" fill="red" stroke="blue" stroke-width="2" /> </svg> So my actual question is how to delete the first or overwrite it or I need a different approach.
Use ios::trunc instead of ios::app Using std::ios::app in the constructor for your std::ofstream tells the program to append to the file and not overwrite it. If you want to overwrite it (ie truncate), then using std::ios::trunc will tell the program to overwrite the existing file. ofstream does this by default, so you could just write the initialization as just std::ofstream newFile(filePath);. Also, don't try to read the file and write to it at the same time; that won't work. Use ifstream to get the data into the buffer, then use close() to close the file. Then initialize newFile to overwrite the file and write out the buffer.
xsl:for-each-group with a condition producing extra output
I am working on to produce text output file from an xml. The XML entries will have a node called as LoanAmt whose value could be 0 or more than zero. Now, I have to check two conditions, first of which is to see if the value of LoanAmt is greater than 0, and then if it is I have to sum up the entries of LoanAmt if for unique Participant enntries. In other words if there is only one Participant ID in the whole xml then display the output but if there are more than one Partcipant ID then only one record for each unique Particpant ID should be populated but the LoanAmt within each unique Particpant ID should be summed up and displayed. My issue is that my xslt is working the same way as I want but the groupby and if condition is not working on the first entry of xml where Loan Amt is not greater than zero. So, the first entry that I am getting is being displayed with zero amount and this line should not appear. This is the XML which is not the complete set but I have taken a sample out of the original one : <?xml version='1.0' encoding='UTF-8'?> <Report_Data > <Report_Entry> <Participant_ID>033</Participant_ID> <chk>673.58</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Vana</Last_Name> <First_Name>Sag</First_Name> <Middle_Name>N</Middle_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>100.8</PreTaxAmt> <MatchAmt>100.8</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>037</Participant_ID> <chk>2167.89</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Pilay</Last_Name> <First_Name>Saath</First_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>61.81</PreTaxAmt> <MatchAmt>61.81</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>043</Participant_ID> <chk>819.78</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>ouphan</Last_Name> <First_Name>angmala</First_Name> <Gender_Code>2</Gender_Code> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>84.19</PreTaxAmt> <MatchAmt>84.18</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>049</Participant_ID> <chk>2066.54</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Tizili</Last_Name> <First_Name>ard</First_Name> <Gender_Code>1</Gender_Code> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>136.37</PreTaxAmt> <MatchAmt>136.36</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>094</Participant_ID> <chk>946.71</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>holphakdy</Last_Name> <First_Name>Meya</First_Name> <Gender_Code>2</Gender_Code> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>81.25</PreTaxAmt> <MatchAmt>81.25</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>104</Participant_ID> <chk>1183.3</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Sai</Last_Name> <First_Name>Paupl</First_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>234.52</PreTaxAmt> <MatchAmt>234.52</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>128.18</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>106</Participant_ID> <chk>185.44</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Leve</Last_Name> <First_Name>Alen</First_Name> <Middle_Name>S</Middle_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>61.48</PreTaxAmt> <MatchAmt>61.47</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>106</Participant_ID> <chk>0</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Leve</Last_Name> <First_Name>Alen</First_Name> <Middle_Name>S</Middle_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>0</PreTaxAmt> <MatchAmt>0</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>10</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>131</Participant_ID> <chk>508.92</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>th</Last_Name> <First_Name>Pa</First_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>0</PreTaxAmt> <MatchAmt>0</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>153</Participant_ID> <chk>277.2</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Baer</Last_Name> <First_Name>Er</First_Name> <Middle_Name>D</Middle_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>72.39</PreTaxAmt> <MatchAmt>72.38</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>155</Participant_ID> <chk>1250.83</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>Piye</Last_Name> <First_Name>Shirit</First_Name> <Middle_Name>M</Middle_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>0</PreTaxAmt> <MatchAmt>0</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>96.3</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>170</Participant_ID> <chk>0</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>terner</Last_Name> <First_Name>san</First_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>0</PreTaxAmt> <MatchAmt>0</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>0</LoanAmt> </Report_Entry> <Report_Entry> <Participant_ID>170</Participant_ID> <chk>684.05</chk> <Workers> <FULL_PART_Time_Indicator>1</FULL_PART_Time_Indicator> <Last_Name>terner</Last_Name> <First_Name>san</First_Name> </Workers> <End_Date_from_Pay_Period>2016-01-03-08:00</End_Date_from_Pay_Period> <PreTaxAmt>162.31</PreTaxAmt> <MatchAmt>162.3</MatchAmt> <RothAmt>0</RothAmt> <LoanAmt>210.98</LoanAmt> </Report_Entry> I am putting my xslt that I have used : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" xmlns:functx="http://www.functx.com" > <xsl:variable name="linefeed" select="' '"/> <xsl:variable name="filler" select="' '"/> <xsl:variable name="separator" select="','"/> <xsl:variable name="spaces" select="concat(' ',' ',' ',' ',' ',' ',' ',' ',' ')"/> <xsl:template match="/"> <xsl:call-template name="LoanDataRecord"/> </xsl:template> <xsl:template name="LoanDataRecord"> <xsl:for-each-group select="Report_Data/Report_Entry" group-by="if( LoanAmt[. > 0 ] ) then Participant_ID else '' " > <xsl:variable name="Var1" select="current-grouping-key()"/> <!-- Plan Number --> <xsl:value-of select="substring(concat('768002',$filler),1,6)"/> <xsl:value-of select="$separator"/> <!-- Participant Number --> <xsl:value-of select="substring(concat(Participant_ID,$filler),1,9)"/> <xsl:value-of select="$separator"/> <!-- Loan Amt --> <xsl:value-of select="(sum(current-group()/LoanAmt))"/> <xsl:value-of select="$linefeed"/> </xsl:for-each-group> </xsl:template> </xsl:stylesheet> 768002,033709571,0 768002,104603206,128.18 and so on But I do not want to see the first line which has 0 LoanAmt.
The problem is the <xsl:for-each-group /> instruction. Change it to use a predicate: <xsl:for-each-group select="Report_Data/Report_Entry[LoanAmt > 0 ]" group-by="Participant_ID"> I tested it with your XML, and it works: http://xsltransform.net/bnnZWu. By the way, I added <xsl:output method="text" />, as that's what you probably want.
Element sorting by attribute
I am new to xsl(t). After reading quite some topics about this the confusion ist getting bigger than smaller. I have to transform a subsection of an xml-file by an attribute. <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> <Rechnung AuftragsReferenz="" MarketingCode="KAN00" Auftragsart="Normal" Auftragsherkunft="Schriftlich" AnzahlPakete="1" ZuZahlenderBetrag="94.30" SummeNebenerloeseNetto="6.07" SummeNebenerloeseBrutto="6.50" EnthalteneMWST="7.86" BetragNetto="86.44" BetragBrutto="94.30" Rechnungsdatum="25.05.2012" Rechnungsnummer="123456789" Zahlungskanal="Rechnung"> <RechnungArtikelpositionen> <RechnungArtikelposition EinzelPreisNetto="0.00" EinzelPreisBrutto="0.00" GesamtPreisNetto="0.00" GesamtPreisBrutto="0.00" Menge="1.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="19.00" Steuerbetrag="2.87" Nettobetrag="15.08"/> <Artikelposition Absagekennzeichen="Allein im Rückstand" AbsagekennzeichenId="38" Artikeltyp="Geschenk" ArtikeltypId="8" Zusatztextkennzeichen="1" Zusatztext="" Bestellnummer="82000" Bestellmenge="1.00" Artikelbezeichnung="Dankeschön" Katalogkennzeichen="K4"/> <Ersatzartikel Zusatztextkennzeichen="" Zusatztext="" Bestellnummer="12345" Bestellmenge="1.00" Artikelbezeichnung="Geschenk: EinGeschenk" Katalogkennzeichen="K4"/> </RechnungArtikelposition> <RechnungArtikelposition EinzelPreisNetto="15.08" EinzelPreisBrutto="17.95" GesamtPreisNetto="15.08" GesamtPreisBrutto="17.95" Menge="1.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="19.00" Steuerbetrag="2.87" Nettobetrag="15.08"/> <Artikelposition Absagekennzeichen="Keine Absage" AbsagekennzeichenId="1" Artikeltyp="Verkauf" ArtikeltypId="0" Zusatztextkennzeichen="1" Zusatztext="" Bestellnummer="54321" Bestellmenge="1.00" Artikelbezeichnung="Massageöl Latschenkiefer" Katalogkennzeichen="K4"/> <Ersatzartikel/> </RechnungArtikelposition> <RechnungArtikelposition EinzelPreisNetto="27.99" EinzelPreisBrutto="29.95" GesamtPreisNetto="27.99" GesamtPreisBrutto="29.95" Menge="1.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="7.00" Steuerbetrag="4.99" Nettobetrag="71.36"/> <Artikelposition Absagekennzeichen="Keine Absage" AbsagekennzeichenId="1" Artikeltyp="Verkauf" ArtikeltypId="0" Zusatztextkennzeichen="" Zusatztext="" Bestellnummer="44444" Bestellmenge="1.00" Artikelbezeichnung="Knoblauchkapseln 60 Stück +" Katalogkennzeichen="K4"/> <Ersatzartikel/> </RechnungArtikelposition> <RechnungArtikelposition EinzelPreisNetto="18.64" EinzelPreisBrutto="19.95" GesamtPreisNetto="37.28" GesamtPreisBrutto="39.90" Menge="2.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="7.00" Steuerbetrag="4.99" Nettobetrag="71.36"/> <Artikelposition Absagekennzeichen="Keine Absage" AbsagekennzeichenId="1" Artikeltyp="Verkauf" ArtikeltypId="0" Zusatztextkennzeichen="" Zusatztext="" Bestellnummer="55555" Bestellmenge="2.00" Artikelbezeichnung="Echte Sauerampfer Kapseln 60 St.+" Katalogkennzeichen="K4"/> <Ersatzartikel/> </RechnungArtikelposition> </RechnungArtikelpositionen> <other things /> </Rechnung> The "Artikelposition"s should be sorted by "EinzelPreisBrutto" I tried several variations, the latest being: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:copy-of select="Rechnung"> <xsl:copy-of select="RechnungArtikelpositionen" /> <xsl:apply-templates select="RechnungArtikelposition"> <xsl:sort select="#EinzelPreisBrutto" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy-of> </xsl:template> </xsl:stylesheet> but no sorting occurs. What am I doing wrong? Thank you for your help in advance.
Your XSLT is not actually currently valid the xsl:copy-of function should not contain any elements within it (It is used just to copy an element 'as-is' Also, you need to make sure when you apply the templates for RechnungArtikelposition you are positioned on the correct parent element of RechnungArtikelpositionen. In your code sample, the current posistion would be the document element of the XML. Instead of using xsl:copy-of, try working with the identity template with an extra template to match RechnungArtikelpositionen and then sort the children. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="RechnungArtikelpositionen"> <xsl:copy> <xsl:apply-templates select="#*"/> <xsl:apply-templates select="RechnungArtikelposition"> <xsl:sort select="#EinzelPreisBrutto" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="#*|node()"> <xsl:copy> <xsl:apply-templates select="#*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> When applied to your sample XML, the following is output: <Rechnung AuftragsReferenz="" MarketingCode="KAN00" Auftragsart="Normal" Auftragsherkunft="Schriftlich" AnzahlPakete="1" ZuZahlenderBetrag="94.30" SummeNebenerloeseNetto="6.07" SummeNebenerloeseBrutto="6.50" EnthalteneMWST="7.86" BetragNetto="86.44" BetragBrutto="94.30" Rechnungsdatum="25.05.2012" Rechnungsnummer="123456789" Zahlungskanal="Rechnung"> <RechnungArtikelpositionen> <RechnungArtikelposition EinzelPreisNetto="27.99" EinzelPreisBrutto="29.95" GesamtPreisNetto="27.99" GesamtPreisBrutto="29.95" Menge="1.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="7.00" Steuerbetrag="4.99" Nettobetrag="71.36"/> <Artikelposition Absagekennzeichen="Keine Absage" AbsagekennzeichenId="1" Artikeltyp="Verkauf" ArtikeltypId="0" Zusatztextkennzeichen="" Zusatztext="" Bestellnummer="44444" Bestellmenge="1.00" Artikelbezeichnung="Knoblauchkapseln 60 Stück +" Katalogkennzeichen="K4"/> <Ersatzartikel/> </RechnungArtikelposition> <RechnungArtikelposition EinzelPreisNetto="18.64" EinzelPreisBrutto="19.95" GesamtPreisNetto="37.28" GesamtPreisBrutto="39.90" Menge="2.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="7.00" Steuerbetrag="4.99" Nettobetrag="71.36"/> <Artikelposition Absagekennzeichen="Keine Absage" AbsagekennzeichenId="1" Artikeltyp="Verkauf" ArtikeltypId="0" Zusatztextkennzeichen="" Zusatztext="" Bestellnummer="55555" Bestellmenge="2.00" Artikelbezeichnung="Echte Sauerampfer Kapseln 60 St.+" Katalogkennzeichen="K4"/> <Ersatzartikel/> </RechnungArtikelposition> <RechnungArtikelposition EinzelPreisNetto="15.08" EinzelPreisBrutto="17.95" GesamtPreisNetto="15.08" GesamtPreisBrutto="17.95" Menge="1.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="19.00" Steuerbetrag="2.87" Nettobetrag="15.08"/> <Artikelposition Absagekennzeichen="Keine Absage" AbsagekennzeichenId="1" Artikeltyp="Verkauf" ArtikeltypId="0" Zusatztextkennzeichen="1" Zusatztext="" Bestellnummer="54321" Bestellmenge="1.00" Artikelbezeichnung="Massageöl Latschenkiefer" Katalogkennzeichen="K4"/> <Ersatzartikel/> </RechnungArtikelposition> <RechnungArtikelposition EinzelPreisNetto="0.00" EinzelPreisBrutto="0.00" GesamtPreisNetto="0.00" GesamtPreisBrutto="0.00" Menge="1.00"> <Rechnungnebenerloese/> <RechnungMehrwertsteuer Prozentsatz="19.00" Steuerbetrag="2.87" Nettobetrag="15.08"/> <Artikelposition Absagekennzeichen="Allein im Rückstand" AbsagekennzeichenId="38" Artikeltyp="Geschenk" ArtikeltypId="8" Zusatztextkennzeichen="1" Zusatztext="" Bestellnummer="82000" Bestellmenge="1.00" Artikelbezeichnung="Dankeschön" Katalogkennzeichen="K4"/> <Ersatzartikel Zusatztextkennzeichen="" Zusatztext="" Bestellnummer="12345" Bestellmenge="1.00" Artikelbezeichnung="Geschenk: EinGeschenk" Katalogkennzeichen="K4"/> </RechnungArtikelposition> </RechnungArtikelpositionen> <otherthings/> </Rechnung>