XSLT 2.0 multiple levels in one group - xslt

Question is how do i get my desired output?
I successfully created a group for each <LogistiekeDeelEenheid>
however, the <DeeleenheidAantal> field must also be filled with one value. For <LogistiekeDeelEenheid> 000094 <DeeleenheidAantal> has to be filled with 10 from <Value AttributeID = "att_NumberInCombiProduct"> 10 </Value> in the xsl to transform. And <LogistiekeDeelEenheid> 000072 <DeeleenheidAantal> has to be filled with 20 from <Value AttributeID = "att_NumberInCombiProduct"> 20 </Value> And <LogistiekeDeelEenheid> 000032 <DeeleenheidAantal> has to be filled with 35 from <Value AttributeID = "att_NumberInCombiProduct"> 35 </Value>
The xml to transform:
<Test>
<Product ID="LV-10432200" UserTypeID="CombiLogistiekeVariant">
<Name>1 - TEST1</Name>
<ProductCrossReference ProductID="Product-10430948"
Type="rpp_CombiLogistiekeVariant2Product">
<KeyValue KeyID="key_ProductGTIN">2311111</KeyValue>
<KeyValue KeyID="key_Productnummer">000094</KeyValue>
<MetaData>
<Value AttributeID="att_AantalInCombiProduct">10</Value>
</MetaData>
</ProductCrossReference>
<ProductCrossReference ProductID="Product-10431710"
Type="rpp_CombiLogistiekeVariant2Product">
<KeyValue KeyID="key_ProductGTIN">5449000018885</KeyValue>
<KeyValue KeyID="key_Productnummer">000072</KeyValue>
<MetaData>
<Value AttributeID="att_AantalInCombiProduct">20</Value>
</MetaData>
</ProductCrossReference>
<ProductCrossReference ProductID="Product-10431738"
Type="rpp_CombiLogistiekeVariant2Product">
<KeyValue KeyID="key_ProductGTIN">54419780</KeyValue>
<KeyValue KeyID="key_Productnummer">000032</KeyValue>
<MetaData>
<Value AttributeID="att_AantalInCombiProduct" Changed="true">35
</Value>
</MetaData>
</ProductCrossReference>
<Values>
<Value AttributeID="att_Productnummer">000001</Value>
<Value AttributeID="att_LVStatus" ID="2">Inactief</Value>
<Value AttributeID="att_LVOmschrijving">TEST Config 1</Value>
<Value AttributeID="att_LVNummer">1</Value>
</Values>
<Product ID="Pack-10432212" UserTypeID="Kleinverpakking">
<Name>21 - Kleinverpakking</Name>
<ProductCrossReference ProductID="LV-10432200"
Type="rpp_Verpakking-Kleinverpakking2Kleiner">
<MetaData>
<Value AttributeID="att_AantalInVerpakking">1</Value>
</MetaData>
</ProductCrossReference>
<Values>
<Value AttributeID="att_VerpakkingBreedte" UnitID="unece.unit.CMT">1</Value>
<Value AttributeID="att_VerpakkingGewichtBruto" UnitID="181">1
</Value>
<Value AttributeID="att_LVNummer">1</Value>
<Value AttributeID="att_VerpakkingHoogte" UnitID="unece.unit.CMT">1</Value>
<Value AttributeID="att_Productnummer">000001</Value>
<Value AttributeID="att_VerpakkingDiepte" UnitID="unece.unit.CMT">1</Value>
<Value AttributeID="att_PrimaireGTIN" Derived="true">Primaire GTIN
Ontbreekt
</Value>
</Values>
</Product>
</Product>
</Test>
And must be transformed to:
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>000094</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>10</DeeleenheidAantal>
</LogistiekeDeelEenheid>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>000072</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>20</DeeleenheidAantal>
</LogistiekeDeelEenheid>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>000032</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>35</DeeleenheidAantal>
</LogistiekeDeelEenheid>
My xslt:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:template match="/">
<xsl:apply-templates select="Test/Product"/>
</xsl:template>
<xsl:template match="Test/Product">
<xsl:for-each-group select="//ProductCrossReference[#Type='rpp_CombiLogistiekeVariant2Product']" group-by="//ProductCrossReference/KeyValue[#KeyID='key_Productnummer']">
<xsl:variable select="current-grouping-key()" name="Productnummer"/>
<test>
<xsl:value-of select="../Name"/>
</test>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>
<xsl:value-of select="$Productnummer"/>
</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>
<xsl:value-of select="../ProductCrossReference/MetaData/Value[#AttributeID='att_AantalInCombiProduct']"/>
</DeeleenheidAantal>
</LogistiekeDeelEenheid>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
But if i use this code, i get this result what is incorrect. In the first should be 10 in the second 20 and in the third 35
<?xml encoding="UTF-8" version="1.0"?>
<test>1 - TEST1</test>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>000094</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>10 20 35
</DeeleenheidAantal>
</LogistiekeDeelEenheid>
<test>1 - TEST1</test>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>000072</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>10 20 35
</DeeleenheidAantal>
</LogistiekeDeelEenheid>
<test>1 - TEST1</test>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>000032</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>10 20 35
</DeeleenheidAantal>
</LogistiekeDeelEenheid>

The suggestion I made in the comment, adjusted to the code you have posted later, would result in
<xsl:template match="Test/Product">
<xsl:for-each-group select="ProductCrossReference[#Type='rpp_CombiLogistiekeVariant2Product']"
group-by="KeyValue[#KeyID='key_Productnummer']">
<xsl:variable select="current-grouping-key()" name="Productnummer"/>
<test>
<xsl:value-of select="../Name"/>
</test>
<LogistiekeDeelEenheid>
<DeeleenheidArtikelNummer>
<xsl:value-of select="$Productnummer"/>
</DeeleenheidArtikelNummer>
<DeeleenheidLogistiekeVariant>0</DeeleenheidLogistiekeVariant>
<DeeleenheidCode>1</DeeleenheidCode>
<DeeleenheidLinkType>4</DeeleenheidLinkType>
<DeeleenheidAantal>
<xsl:value-of select="MetaData/Value[#AttributeID='att_AantalInCombiProduct']"/>
</DeeleenheidAantal>
</LogistiekeDeelEenheid>
</xsl:for-each-group>
</xsl:template>
At https://xsltfiddle.liberty-development.net/ei5R4tY I applied the suggestion to your edited input sample and the result has e.g. <DeeleenheidAantal>10</DeeleenheidAantal>, that is, single values for that item in the result.
I must admit that your sample data with the nesting is still not clear to me but feel free to further edit your question and clarify which data you want to process and group.

Related

xslt date conversion to UTC

I am very new to xslt programming. Can any one help with this:
input xml:
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE>
<ER>
<MXITEMOUT xmlns="http://www.mro.com/mx/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="EN">
<Header operation="Notify" event="1">
<SenderID type="MAXIMO" majorversion="6" minorversion="0" build="02" dbbuild="V600-76">MX</SenderID>
<CreationDateTime>2005-08-15T14:28:06-05:00</CreationDateTime>
<RecipientID>EXTSYS1234</RecipientID>
<MessageID>1124</MessageID>
</Header>
<Content>
<MXITEM>
<ITEM action="Add">
<ITEMNUM>I1001</ITEMNUM>
<DESCRIPTION langenabled="1">test item</DESCRIPTION>
<ROTATING>1</ROTATING>
<LOTTYPE maxvalue="NOLOT">NOLOT</LOTTYPE>
<CAPITALIZED>0</CAPITALIZED>
<CREATEDDATE>2014-05-22T13:00:46+10:00</CREATEDDATE>
</ITEM>
</MXITEM>
</Content>
</MXITEMOUT>
</ER>
<IR>
<MXITEMOUT xmlns="http://www.mro.com/mx/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="EN">
<Header operation="Notify" event="1">
<SenderID type="MAXIMO" majorversion="6" minorversion="0" build="02" dbbuild="V600-76">MX</SenderID>
<CreationDateTime>2005-08-15T14:28:06-05:00</CreationDateTime>
<RecipientID>EXTSYS1234</RecipientID>
<MessageID>1124</MessageID>
</Header>
<Content>
<MXITEM>
<ITEM action="Add">
<ITEMNUM>I1001</ITEMNUM>
<DESCRIPTION langenabled="1">test item</DESCRIPTION>
<ROTATING>1</ROTATING>
<LOTTYPE maxvalue="NOLOT">NOLOT</LOTTYPE>
<CAPITALIZED>0</CAPITALIZED>
<CREATEDDATE>2014-05-22T13:00:46+10:00</CREATEDDATE>
</ITEM>
</MXITEM>
</Content>
</MXITEMOUT>
</IR>
</MESSAGE>
My XSLT is:
<?xml version="1.0"?>
<!--
This XSL is supposed to change the ITEMNUM tag value by prepending 001 to the existing value.
It also strips off the MESSAGE and IR wrapper tags so that the resultant data is consistent with
our XML schema
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mro="http://www.mro.com/mx/integration" version="1.0" exclude-result-prefixes="mro">
<xsl:template match="/MESSAGE">
<xsl:apply-templates select="IR"/>
</xsl:template>
<xsl:template match="IR">
<xsl:apply-templates select="#*|*|text()"/>
</xsl:template>
<xsl:template match="#*|*|text()">
<xsl:copy>
<xsl:apply-templates select="#*|*|text()"/>
</xsl:copy>
</xsl:template>
<!--
Change the ITEMNUM tag value by prepending 001 to the existing value
-->
<xsl:template match="mro:ITEMNUM">
<xsl:element name="ITEMNUM" namespace="http://www.mro.com/mx/integration">
<xsl:text>MAX-</xsl:text><xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Current output is:
<?xml version="1.0" encoding="UTF-8"?>
<MXITEMOUT xmlns="http://www.mro.com/mx/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="EN">
<Header operation="Notify" event="1">
<SenderID type="MAXIMO" majorversion="6" minorversion="0" build="02" dbbuild="V600-76">MX</SenderID>
<CreationDateTime>2005-08-15T14:28:06-05:00</CreationDateTime>
<RecipientID>EXTSYS1234</RecipientID>
<MessageID>1124</MessageID>
</Header>
<Content>
<MXITEM>
<ITEM action="Add">
<mro:ITEMNUM xmlns:mro="http://www.mro.com/mx/integration">MAX-I1001</mro:ITEMNUM>
<DESCRIPTION langenabled="1">test item</DESCRIPTION>
<ROTATING>1</ROTATING>
<LOTTYPE maxvalue="NOLOT">NOLOT</LOTTYPE>
<CAPITALIZED>0</CAPITALIZED>
<CREATEDDATE>2014-05-22T13:00:46+10:00</CREATEDDATE>
</ITEM>
</MXITEM>
</Content>
</MXITEMOUT>
Expected output is:
<?xml version="1.0" encoding="UTF-8"?>
<MXITEMOUT xmlns="http://www.mro.com/mx/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="EN">
<Header operation="Notify" event="1">
<SenderID type="MAXIMO" majorversion="6" minorversion="0" build="02" dbbuild="V600-76">MX</SenderID>
<CreationDateTime>2005-08-15T14:28:06-05:00</CreationDateTime>
<RecipientID>EXTSYS1234</RecipientID>
<MessageID>1124</MessageID>
</Header>
<Content>
<MXITEM>
<ITEM action="Add">
<mro:ITEMNUM xmlns:mro="http://www.mro.com/mx/integration">MAX-I1001</mro:ITEMNUM>
<DESCRIPTION langenabled="1">test item</DESCRIPTION>
<ROTATING>1</ROTATING>
<LOTTYPE maxvalue="NOLOT">NOLOT</LOTTYPE>
<CAPITALIZED>0</CAPITALIZED>
<CREATEDDATE>2014-05-22T23:00:46.000Z</CREATEDDATE>
</ITEM>
</MXITEM>
</Content>
</MXITEMOUT>
I am trying find logic in google to convert date to utc format in xslt.
It is throwing strange errors.
XML date:2014-05-22T13:00:46+10:00 Expected Date: 2014-05-22T23:00:46.000Z

complex variables in xslt template v1, v2

I have source xml looking like this :
<Data>
<ActionPlaces>
<ActionPlace>
<ActionPlaceID>74</ActionPlaceID>
<PlaceName>Theatre Of Classic</PlaceName>
</ActionPlace>
</ActionPlaces>
<Actions>
<CommonAction Id="2075" Name="King">
<Action>
<ActionID>4706</ActionID>
<ActionPlaceID>74</ActionPlaceID>
</Action>
</CommonAction>
</Actions>
</Data>
Which is to transform to this:
<category name="King">
<name>King</name>
<parent name="Theatre Of Classic" />
</category>
I want to use variable :
<xsl:template match="ActionPlaces">
<xsl:variable name="id" select="/ActionPlace/ActionPlaceID"/>
<xsl:template match="CommonAction" >
<category name="<xsl:value-of select="#name"/> >
<name><xsl:value-of select="#name"/></name>
<parent <xsl:if test="/Action/ActionPlaceID = $id">
name=/Action/ActionPlaceID/> <- how to get name of theatre here?
</xsl:template>
Can variable store not only id but name also? And how to get it? What is the most common approach to handle this ?
Here's one option using XSL keys (as #michael-hor257k suggested):
Input
<Root>
<ActionPlaces>
<ActionPlace>
<ActionPlaceID>74</ActionPlaceID>
<PlaceName>Theatre Of Classic</PlaceName>
</ActionPlace>
</ActionPlaces>
<Actions>
<CommonAction Id="2075" Name="King">
<Action>
<ActionID>4706</ActionID>
<ActionPlaceID>74</ActionPlaceID>
</Action>
</CommonAction>
</Actions>
</Root>
Stylesheet
<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"/>
<!-- Collect all <ActionPlace> elements into an XSL key -->
<xsl:key name="ActionPlaceById" match="ActionPlace" use="ActionPlaceID"/>
<xsl:template match="/">
<xsl:apply-templates select="Root/Actions/CommonAction"/>
</xsl:template>
<xsl:template match="CommonAction">
<category name="{#Name}">
<name>
<xsl:value-of select="#Name"/>
</name>
<!--
Using the ActionPlaceById key we created earlier, fetch the <ActionPlace>
element that has an <ActionPlaceID> child that has the same value as the
<ActionPlaceID> descendant of the current <CommonAction> element.
-->
<parent name="{key('ActionPlaceById', Action/ActionPlaceID)/PlaceName}"/>
</category>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="utf-8"?>
<category name="King">
<name>King</name>
<parent name="Theatre Of Classic"/>
</category>

XSLT getting grandchild node attribute values in template

Given XML like this:
<?xml version="1.0" encoding="UTF-8"?>
<Products>
<Product someId="1EFAD9659EC">
<Identifiers>
<Identifier Id="234532423" Name="globalTradeItemNumber (GTIN)" Value="00671657621322" />
<Identifier Id="99845898" Name="Internal Supplier Part #" Value="DEL 20 10B015000" />
<Identifier Id="49348598" Name="MFG Model # (Series)" Value="DEL 20 10B015000" />
<Identifier Id="439854985" Name="MFG Part # (OEM)" Value="DEL 20 10B015000" />
<Identifier Id="2349832489" Name="UPC" Value="671657621322" />
</Identifiers>
</Product>
<Product someId="1EFAD9659EC">
<Identifiers>
<Identifier Id="234532423" Name="globalTradeItemNumber (GTIN)" Value="51651518" />
<Identifier Id="99845898" Name="Internal Supplier Part #" Value="TIM 20 10B015000" />
<Identifier Id="49348598" Name="MFG Model # (Series)" Value="TOM 20 10B015000" />
<Identifier Id="439854985" Name="MFG Part # (OEM)" Value="TAK 20 10B015000" />
<Identifier Id="2349832489" Name="UPC" Value="87468387468" />
</Identifiers>
</Product>
. . .
I want to end up with something like
...
<Product upc="671657621322"/>
<Product upc="87468387468"/>
...
But what I'm getting is
...
<Product upc="true"/>
<Product upc="true"/>
...
I keep getting the boolean answer to my select rather than the value of the attribute. What silly thing am I doing wrong here? This is the XSLT I'm trying:
...
<xsl:template match="/">
<Output>
<xsl:apply-templates />
</Output>
</xsl:template>
<xsl:template match="Product">
<xsl:variable name="productCode" select="./Identifiers/Identifier/#Name='UPC'"/>
<Product upc="{$productCode}">
</Product>
</xsl:template>
...
Thanks.
You are using the wrong xpath selection. Use:
select="Identifiers/Identifier[#Name='UPC']/#Value"
If you are interested only with those two node values match them with the template:
<xsl:template match="Product/Identifiers/Identifier[#Name='UPC']">
<xsl:variable name="productCode" select="#Value"/>
<Product upc="{$productCode}">
</Product>
</xsl:template>

XSLT is not recurring tags or selecting first tag

I'm having two problems trying to process XML that has recursive tags (the same tag repeating within the tag).
Problem #1 the "Caption:" part outputs the text concatination of all the caption tags, it is as if it is searching from / and not the path it was invoked by.
Problem #2 #id test finds nothing, which is probably a symptom of the same problem.
Here is the XSL:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<xsl:template match="cog:rows">
<xsl:apply-templates select="cog:rowEdge"/>
</xsl:template>
<xsl:template match="cog:rowEdge">
<p><b>Caption:</b> <xsl:value-of select="cog:caption"/></p>
<xsl:if test="#id">
<b>id:</b> <xsl:value-of select="#id"/><br/>
</xsl:if>
<xsl:if test="cog:rowEdge">
<p>Looking at next rowEdge</p>
<xsl:apply-templates select="cog:rowEdge"/>
</xsl:if>
</xsl:template>
<html>
<head><title>%s</title></head>
<body>
<xsl:apply-templates select="cog:dataset/cog:crosstab/cog:rows"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Here is the XML:
<?xml version="1.0" encoding="utf-8" ?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<crosstab>
<values>
<value row="R1" col="C1" xs:nil="true" />
<value row="R1" col="C2" xs:nil="true" />
<value row="R1" col="C3" xs:nil="true" />
<value row="R1" col="C4" xs:nil="true" />
<value row="R1" col="C5" xs:nil="true" />
<value row="R1" col="C6" xs:nil="true" />
<value row="R1" col="C7" xs:nil="true" />
<value row="R1" col="C8" xs:nil="true" />
<value row="R1" col="C9" xs:nil="true" />
<value row="R2" col="C1">0</value>
<value row="R2" col="C2">12.61728395</value>
<value row="R2" col="C3">1320.40677966</value>
<value row="R2" col="C4">7</value>
<value row="R2" col="C5">1.90318499</value>
<value row="R2" col="C6">108.66456135</value>
<value row="R2" col="C7">776.61407946</value>
<value row="R2" col="C8">-0.86007907</value>
<value row="R2" col="C9">46.53571429</value>
</values>
<corner>
<caption>Time Period: DCG Incurred Paid Year</caption>
</corner>
<columns>
<colEdge>
<caption>Jan 02 to Dec 02 {All Data} CRxIp</caption>
<colEdge>
<caption>2002</caption>
<colEdge id="C1">
<caption>Member Age Avg</caption>
</colEdge>
<colEdge id="C2">
<caption>Days Supply Per Script Rx</caption>
</colEdge>
<colEdge id="C3">
<caption>Net Pay Per Pat Med</caption>
</colEdge>
<colEdge id="C4">
<caption>Days LOS Admit Acute</caption>
</colEdge>
<colEdge id="C5">
<caption>Days LOS Admit Acute</caption>
</colEdge>
<colEdge id="C6">
<caption>Allow Amt PMPM Med and Rx {Cmpl}</caption>
</colEdge>
<colEdge id="C7">
<caption>Allow Amt PMPM Med and Rx {Cmpl}</caption>
</colEdge>
<colEdge id="C8">
<caption>% Diff Allow Amt PMPM Med and Rx {Cmpl}</caption>
</colEdge>
<colEdge id="C9">
<caption>Relative Risk Score Prosp Explan NonRescaled</caption>
</colEdge>
</colEdge>
</colEdge>
</columns>
<rows>
<rowEdge>
<caption>Subsets</caption>
<rowEdge>
<caption>Plan Type Medstat</caption>
<rowEdge id="R1">
<caption>Cohort Medstat</caption>
</rowEdge>
</rowEdge>
</rowEdge>
<rowEdge>
<caption>Chronic Episodes</caption>
<rowEdge>
<caption>HMO (Managed Care)</caption>
<rowEdge id="R2">
<caption>Females, Ages < 1</caption>
</rowEdge>
</rowEdge>
</rowEdge>
</rows>
</crosstab>
</dataset>
Your stylesheet is not valid because the template for the document node wraps all others. Templates are top-level elements in XSLT, and must not be nested. If you separate them, the stylesheet should work as expected:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<html>
<head><title>%s</title></head>
<body>
<xsl:apply-templates select="cog:dataset/cog:crosstab/cog:rows"/>
</body>
</html>
</xsl:template>
<xsl:template match="cog:rows">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="cog:rowEdge">
<p><b>Caption:</b> <xsl:value-of select="cog:caption"/></p>
<xsl:if test="#id">
<b>id:</b> <xsl:value-of select="#id"/><br/>
</xsl:if>
<xsl:if test="cog:rowEdge">
<p>Looking at next rowEdge</p>
<xsl:apply-templates select="cog:rowEdge"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Xslt for-each and key match

I have two xml data sources like this:
<orders>
<order>
<ordernumber>123</ordernumber>
<subtotal>20</subtotal>
<total>23.5</total>
</order>
<order>
<ordernumber>234</ordernumber>
<subtotal>19</subtotal>
<total>26.5</total>
</order>
</orders>
<orderitems>
<item>
<ordernumber>123</ordernumber>
<productname>test1</productname>
<sku>s9sdidk</sku>
<item>
<item>
<ordernumber>123</ordernumber>
<productname>test2</productname>
<sku>123232</sku>
<item>
<item>
<ordernumber>234</ordernumber>
<productname>test3</productname>
<sku>s9sd2d32k</sku>
<item>
<item>
<ordernumber>234</ordernumber>
<productname>test4</productname>
<sku>s9swe23</sku>
<item>
</orderitems>
and then I need to use xslt to group items by order number and get an output like this:
productname sku
test1 s9sdidk
test2 123232
---------------------------------
subtotal: 20
total: 23.5
productname sku
test3 s9sd2d32k
test4 s9swe23
---------------------------------
subtotal: 19
total: 26.5
I need to use html tags so I can't use for-each-group thing...please help!
thanks in advance.
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kItemByOrdernumber" match="item" use="ordernumber"/>
<xsl:variable name="vSource2" select="document('source2.xml')"/>
<xsl:template match="text()"/>
<xsl:template match="order/ordernumber">
<xsl:variable name="vCurrent" select="."/>
<xsl:text>productname sku
</xsl:text>
<xsl:for-each select="$vSource2">
<xsl:apply-templates
select="key('kItemByOrdernumber',$vCurrent)"/>
</xsl:for-each>
<xsl:value-of
select="concat('---------------------------------','
',
' subtotal: ',../subtotal,'
',
' total: ',../total,'
')"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="concat(productname,' ',
sku,'
')"/>
</xsl:template>
</xsl:stylesheet>
With first document as input and second document as source2.xml external input, output:
productname sku
test1 s9sdidk
test2 123232
---------------------------------
subtotal: 20
total: 23.5
productname sku
test3 s9sd2d32k
test4 s9swe23
---------------------------------
subtotal: 19
total: 26.5
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kitemByOrder" match="item" use="ordernumber"/>
<xsl:param name="pmaxSize" select="100"/>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="order">
productname<xsl:text> </xsl:text>sku
<xsl:apply-templates select="key('kitemByOrder', ordernumber)"/>
---------------------------------
subtotal: <xsl:value-of select="subtotal"/>
total: <xsl:value-of select="total"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="concat(productname, ' ', sku, '
')"/>
</xsl:template>
<xsl:template match="orderitems"/>
</xsl:stylesheet>
when applied on the provided XML document (corrected as it was severely non-well-formed):
<t>
<orders>
<order>
<ordernumber>123</ordernumber>
<subtotal>20</subtotal>
<total>23.5</total>
</order>
<order>
<ordernumber>234</ordernumber>
<subtotal>19</subtotal>
<total>26.5</total>
</order>
</orders>
<orderitems>
<item>
<ordernumber>123</ordernumber>
<productname>test1</productname>
<sku>s9sdidk</sku>
</item>
<item>
<ordernumber>123</ordernumber>
<productname>test2</productname>
<sku>123232</sku>
</item>
<item>
<ordernumber>234</ordernumber>
<productname>test3</productname>
<sku>s9sd2d32k</sku>
</item>
<item>
<ordernumber>234</ordernumber>
<productname>test4</productname>
<sku>s9swe23</sku>
</item>
</orderitems>
</t>
produces the wanted, correct result:
productname sku
test1 s9sdidk
test2 123232
---------------------------------
subtotal: 20
total: 23.5
productname sku
test3 s9sd2d32k
test4 s9swe23
---------------------------------
subtotal: 19
total: 26.5
Note: You may use two different XML documents for the two data sources, but the processing is essentially the same, with the exception that you need to address one of them using the document() function.