Increment 10 for each node exists in xslt - xslt

Starting with 10 and Need to increment 10 for each node of the order item is exists
Can please anyone help me to achieve this output. need XSLT 2.0 code for this output
Starting with 10 and Need to increment 10 for each node of the order item is exists
Can please anyone help me to achieve this output. need XSLT 2.0 code for this output
Starting with 10 and Need to increment 10 for each node of the order item is exists
Can please anyone help me to achieve this output. need XSLT 2.0 code for this output
Starting with 10 and Need to increment 10 for each node of the order item is exists
Can please anyone help me to achieve this output. need XSLT 2.0 code for this output
Input:
<orderHeader>
<distributionChannelCode>ABC</distributionChannelCode>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
<orderItem>
</orderItem>
</orderHeader>
OutPut:
<orderHeader>
<distributionChannelCode>ABC</distributionChannelCode>
<orderItem>
<productCode>10</productCode>
</orderItem>
<orderItem>
<productCode>20</productCode>
</orderItem>
<orderItem>
<productCode>30</productCode>
</orderItem>
<orderItem>
<productCode>40</productCode>
</orderItem>
<orderItem>
<productCode>50</productCode>
</orderItem>
<orderItem>
<productCode>60</productCode>
</orderItem>
<orderItem>
<productCode>70</productCode>
</orderItem>
<orderItem>
<productCode>80</productCode>
</orderItem>
<orderItem>
<productCode>90</productCode>
</orderItem>
</orderHeader>

<xsl:template match="orderItem">
<xsl:copy>
<productCode><xsl:value-of select="position()*10"/>
</xsl:copy>
</xsl:template>

Related

Condition based filtering for the target field

Below is my xml input
<?xml version="1.0" encoding="UTF-8"?>
<DELVRY07>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM>EDI_DC40</TABNAM>
<MANDT>100</MANDT>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<VBELN>0080000646</VBELN>
<VSTEL>1710</VSTEL>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>AG</PARTNER_Q>
<PARTNER_ID>0017100001</PARTNER_ID>
<JURISDIC>GA00000000</JURISDIC>
<LANGUAGE>EN</LANGUAGE>
<FORMOFADDR>Company</FORMOFADDR>
<NAME1>Domestic US Customer 1</NAME1>
</E1ADRM1>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>SP</PARTNER_Q>
<PARTNER_ID>PL1047</PARTNER_ID>
<LANGUAGE>EN</LANGUAGE>
<NAME1>W. L. GORE & ASSOCIATES, INC</NAME1>
</E1ADRM1>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>WE</PARTNER_Q>
<PARTNER_ID>0017100001</PARTNER_ID>
<JURISDIC>GA00000000</JURISDIC>
<LANGUAGE>EN</LANGUAGE>
<FORMOFADDR>Company</FORMOFADDR>
<NAME1>Domestic US Customer 1</NAME1>
</E1ADRM1>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>OSP</PARTNER_Q>
<PARTNER_ID>1710</PARTNER_ID>
<JURISDIC>7700000000</JURISDIC>
<LANGUAGE>EN</LANGUAGE>
<NAME1>Shipping Point 1710 - Address Name 1</NAME1>
</E1ADRM1>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>OSO</PARTNER_Q>
<PARTNER_ID>1710</PARTNER_ID>
<JURISDIC>7700000000</JURISDIC>
<LANGUAGE>EN</LANGUAGE>
<NAME1>Sales Organization 1710 - Address Name 1</NAME1>
</E1ADRM1>
</E1EDL20></IDOC></DELVRY07>
in the above xml I need to filter out the condtion for PARTNER_Q. if PARTNER_Q =WE then pass the value of related NAME1 field value to the target.
I have tried below XSL code but not able get the correct logic for filtering
<xsl:variable name="vPartnerfunction" select="$nodes_in/PARTNER_Q"/>
<xsl:variable name="vName" select="$nodes_in/NAME1"/>
<xsl:choose>
<xsl:when test="$vPartnerfunction = 'WE'">
<xsl:value-of select="$vName"/>
</xsl:when>
</xsl:choose>
Please help me out on this.
In the output only i should get the below value
<NAME1>Domestic US Customer 1</NAME1>
The result you show can be produced quite easily by:
<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="/DELVRY07">
<xsl:copy-of select="IDOC/E1EDL20/E1ADRM1[PARTNER_Q='WE']/NAME1"/>
</xsl:template>
</xsl:stylesheet>
However, if there are more than one E1ADRM1 element that meets the condition, the result will be an XML fragment - not a well-formed XML document.

Add the total amount and add it to a new tag

I have the input
<Invoice>
<Invoice_Details>
<Consolidated_Invoice_ID>1</Consolidated_Invoice_ID>
<Line>1</Line>
<Gross_Invoice_Amount>1110</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>1</Consolidated_Invoice_ID>
<Line>2</Line>
<Gross_Invoice_Amount>1110</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>2</Consolidated_Invoice_ID>
<Line>1</Line>
<Gross_Invoice_Amount>2220</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>2</Consolidated_Invoice_ID>
<Line>2</Line>
<Gross_Invoice_Amount>2220</Gross_Invoice_Amount>
</Invoice_Details>
</Invoice>
I want the ouput of the format:
<Invoice>
<Invoice_Details>
<Consolidated_Invoice_ID>1</Consolidated_Invoice_ID>
<Line>1</Line>
<Gross_Invoice_Amount>1110</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>1</Consolidated_Invoice_ID>
<Line>2</Line>
<Gross_Invoice_Amount>1110</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>1</Consolidated_Invoice_ID>
<Line>3</Line>
<Gross_Invoice_Amount>22220</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>2</Consolidated_Invoice_ID>
<Line>1</Line>
<Gross_Invoice_Amount>2220</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>2</Consolidated_Invoice_ID>
<Line>2</Line>
<Gross_Invoice_Amount>2220</Gross_Invoice_Amount>
</Invoice_Details>
<Invoice_Details>
<Consolidated_Invoice_ID>2</Consolidated_Invoice_ID>
<Line>3</Line>
<Gross_Invoice_Amount>4440</Gross_Invoice_Amount>
</Invoice_Details>
</Invoice>
The values of the invoice ID and the line value are to be created as a new elements that add the gross of all the same ids.
Condition:
The value of gross is required only when there is atleast one value of gross in any of the available ids.if no gross is avilable then it is not required.
Here is an XSLT 1.0 solution:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:key name="invoices" match="Invoice/Invoice_Details" use="Consolidated_Invoice_ID"/>
<xsl:template match="/">
<Invoice>
<xsl:for-each select="Invoice/Invoice_Details[count(.|key('invoices',Consolidated_Invoice_ID)[1])=1]">
<xsl:variable name="details" select="key('invoices',Consolidated_Invoice_ID)"/>
<xsl:copy-of select="$details"/>
<!--Add a new record with gross amount and total-->
<Consolidated_Invoice_ID>
<xsl:value-of select="Consolidated_Invoice_ID"/>
</Consolidated_Invoice_ID>
<Line>
<xsl:value-of select="count($details)+1"/>
</Line>
<Gross_Invoice_Amount>
<xsl:value-of select="sum($details/Gross_Invoice_Amount)"/>
</Gross_Invoice_Amount>
</xsl:for-each>
</Invoice>
</xsl:template>
</xsl:transform>

How to iterate counter in XSLT 1.0 based on some condition

I have a requirement where I have to increment the count and assign that value to one of the target element.
For ex - My input request is something like this
<Deliveries>
<Delivery>
<OrderNo>
1234
</OrderNo>
<orderItem>
12
</orderItem>
</Delivery>
<Delivery>
<OrderNo>
S1234
</OrderNo>
<orderItem>
12
</orderItem>
</Delivery>
</Deliveries>
Delivery is parent element which is unbounded and my output XSD is nothing but table columns.
<Order_table>
<Orders>
<column1>
<column2>
</Orders>
</Order_table>
Now My requirement is that If OrderNo contains first letter as S then I have to assign 1 value to column1 else I have to simply copy the value of orderItem. and every time I get the OrderNo value starting with S then I have to increment the value by 1 but if orderNo is not starting with S then it should not increase by 1. Due to this logic , I am not able to use position function as well.
For example -
If my input is something like -
<Deliveries>
<Delivery>
<OrderNo>
S1234
</OrderNo>
<orderItem>
12
</orderItem>
</Delivery>
<Delivery>
<OrderNo>
1234
</OrderNo>
<orderItem>
12
</orderItem>
</Delivery>
<Delivery>
<OrderNo>
S1234
</OrderNo>
<orderItem>
12
</orderItem>
</Delivery>
</Deliveries>
Then my output should be -
<Order_table>
<Orders>
<column1>1</column1> <-- First value as 1 as Order starts from S
<column2>
</Orders>
<Orders>
<column1>12</column1> copy of orderItem bcz orderNo don't start with S
<column2>
</Orders>
<Orders>
<column1>2</column1> Increment from 1 to 2 as Order again starts from S
<column2>
</Orders>
</Order_table>
Could any please help me with my issue ? A piece of code will help me a lot.
Try:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Order_table>
<xsl:apply-templates select="//OrderNo"/>
</Order_table>
</xsl:template>
<xsl:template match="OrderNo[starts-with(normalize-space(.), 'S')]">
<Orders>
<column1>
<xsl:number level="any" count="OrderNo[starts-with(normalize-space(.), 'S')]"/>
</column1>
<column2/>
</Orders>
</xsl:template>
<xsl:template match="OrderNo">
<Orders>
<column1><xsl:value-of select="normalize-space(../orderItem)"/></column1>
<column2/>
</Orders>
</xsl:template>
</xsl:stylesheet>
When your context is placed at a Delivery node, test for starts-with(OrderNo,'S'), then count backward the number of siblings using the same test. This will give you your incrementing value.
<xsl:template match="Delivery">
<Orders>
<column1>
<xsl:choose>
<xsl:when test="starts-with(OrderNo,'S')">
<xsl:value-of select="1+count(preceding-sibling::Delivery[starts-with(OrderNo,'S')])"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="orderItem"/>
</xsl:otherwise>
</xsl:choose>
</column1>
<column2/>
</Orders>
</xsl:template>
You will of course, also need complete the remainder of the stylesheet yourself, but this covers the logical that you outline in your question.

for each in for each logic

I am trying to do following in XSLT 1.0:
Copy all the Fram element as is into output, where the condition is any of Fram's attributes (#name AND #type AND #ref) value matches with any XFram element then it should update the Fram/text() with XFram/text(). After that copy rest of XFram element (all those dint match the above criteria) and convert them into Fram tag.
Note: Third Fram element's all attribute matches with third Xfram element, hence text appended in Third Fram element. Rest of XFarm element got transform into Fram element and added after last Fram element. Also you will notice that Fram's order is not changed.
Input.XML
<Doc>AL
<Frams>
<Fram type="x" name="Fram1" ref="ref1">This is Fram One</Fram>
<Fram type="y" name="Fram2" ref="ref2">This is Fram Two</Fram>
<Fram type="z" name="Fram3" ref="ref3">This is Fram Three</Fram>
<Fram type="a" name="Fram4" ref="ref3">This is Fram Four</Fram>
<Fram type="b" name="Fram5" ref="ref3">This is Fram Five</Fram>
</Frams>
<XFram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram One</Fram>
<XFram type="f" name="XFram2" ref="Xref2">This is XFram Two</Fram>
<XFram type="z" name="XFram3" ref="Xref3">This is XFram Three</Fram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram Four</Fram>
<XFram>
<Doc>
Output should be:
<Doc>
<Frams>
<Fram type="x" name="Fram1" ref="ref1">This is Fram One</Fram>
<Fram type="y" name="Fram2" ref="ref2">This is Fram Two</Fram>
<Fram type="z" name="Fram3" ref="ref3">This is XFram Three</Fram>
<Fram type="a" name="Fram4" ref="ref3">This is Fram Four</Fram>
<Fram type="b" name="Fram5" ref="ref3">This is Fram Five</Fram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram One</Fram>
<XFram type="f" name="XFram2" ref="Xref2">This is XFram Two</Fram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram Four</Fram>
</Frams>
<Doc>
I am doing something like this but not able to think of the logic:
<xsl:template match="/">
<xsl:for-each select="XFram">
<xsl:variable name="type">
<xsl:value-of select="type"/>
</xsl:variable>
<xsl:variable name="name">
<xsl:value-of select="name"/>
</xsl:variable>
<xsl:variable name="ref">
<xsl:value-of select="ref"/>
</xsl:variable>
<xsl:for-each select="//Fram">
<xsl:choose>
<xsl:when test="(type = $type) and (name = $name) and (ref = $ref)"> </xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
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()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Fram[last()]">
<xsl:call-template name="identity"/>
<xsl:apply-templates
select="../../XFram/*"/>
</xsl:template>
<xsl:template match="XFram/XFram">
<xsl:if test=
"not(/*/Frams/*
[#type = current()/#type
and
concat('X',#name) = current()/#name
and
concat('X',#ref) = current()/#ref
]
)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
<xsl:template match="XFram"/>
</xsl:stylesheet>
when applied on the provided XML document (with corrected severe malformedness!!!):
<Doc>
<Frams>
<Fram type="x" name="Fram1" ref="ref1">This is Fram One</Fram>
<Fram type="y" name="Fram2" ref="ref2">This is Fram Two</Fram>
<Fram type="z" name="Fram3" ref="ref3">This is Fram Three</Fram>
<Fram type="a" name="Fram4" ref="ref3">This is Fram Four</Fram>
<Fram type="b" name="Fram5" ref="ref3">This is Fram Five</Fram>
</Frams>
<XFram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram One</XFram>
<XFram type="f" name="XFram2" ref="Xref2">This is XFram Two</XFram>
<XFram type="z" name="XFram3" ref="Xref3">This is XFram Three</XFram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram Four</XFram></XFram>
</Doc>
produces the wanted, correct result:
<Doc>
<Frams>
<Fram type="x" name="Fram1" ref="ref1">This is Fram One</Fram>
<Fram type="y" name="Fram2" ref="ref2">This is Fram Two</Fram>
<Fram type="z" name="Fram3" ref="ref3">This is Fram Three</Fram>
<Fram type="a" name="Fram4" ref="ref3">This is Fram Four</Fram>
<Fram type="b" name="Fram5" ref="ref3">This is Fram Five</Fram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram One</XFram>
<XFram type="f" name="XFram2" ref="Xref2">This is XFram Two</XFram>
<XFram type="e" name="XFram1" ref="Xref1">This is XFram Four</XFram>
</Frams>
</Doc>

How do i transform a number to a repetition of characters in XSLT?

I have the following input:
<node TEXT="txt">
<node TEXT="txt">
<node TEXT="txt"/>
<node TEXT="txt"/>
</node>
<node TEXT="txt"/>
</node>
<node TEXT="txt"/>
I am currently using:
<xsl:number level="multiple" count="node" format="1"/>
within an XSTL script to receive the following output:
1 txt
1.1 txt
1.1.1 txt
1.1.2 txt
1.2 txt
2 txt
but i want to have this output:
* txt
** txt
*** txt
*** txt
** txt
* txt
Can you help me?
PS: I want to convert a freemind map to basic mediawiki list syntax. And yes! i am aware that there are several ways to get native freemind maps into media wikis, but i need the conversion of the <node>-tree to ***-lists
One simple way to do this is to just translate the result of the <xsl:number/> into the wanted format.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node">
<xsl:variable name="vIndent">
<xsl:number level="multiple" count="node"/>
</xsl:variable>
<xsl:value-of select=
"concat(translate($vIndent,
'1234567890.',
'**********'),
' ',
#TEXT,
'
'
)"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
when applied on this XML document:
<t>
<node TEXT="txt">
<node TEXT="txt">
<node TEXT="txt"/>
<node TEXT="txt"/></node>
<node TEXT="txt"/></node>
<node TEXT="txt"/>
</t>
produces the wanted result:
* txt
** txt
*** txt
*** txt
** txt
* txt
Note the use of the translate() function to discard any "." characters and to translate any digit into an "*".