XSLT - create new elements and values - xslt

This is the original input file
<?xml version="1.0" encoding="UTF-8" ?>
<SSC>
<Payload>
<Item>
<Characteristics>
<CharacteristicCode>NRF COLOR</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>NRF COLOR</CharacteristicCode>
<DiscreteValueAlphanumeric>000</DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
<Characteristics>
<CharacteristicCode>SIZE</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>SIZE</CharacteristicCode>
<DiscreteValueAlphanumeric>10</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>SIZE</CharacteristicCode>
<DiscreteValueAlphanumeric>11</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>SIZE</CharacteristicCode>
<DiscreteValueAlphanumeric>12</DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
<Characteristics>
<CharacteristicCode>UPC</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric></DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
</Item>
</Payload>
</SSC>
Based on the Characteristic Code "SIZE", I need to append the file with an additional Characteristic element called "UPC". For each Size, a UPC code will be created. So the end result would be like this
<Characteristics>
<CharacteristicCode>UPC</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>UPC-10</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>UPC-11</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>UPC-12</DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
Here's my code so far. I was not able to concatenate 'UPC' in the field due to the problem with the loop
<xsl:template match="/SSC/Payload/Item/Characteristics/AlphaValues[CharacteristicCode='UPC']">
<xsl:for-each select = "/SSC/Payload/Item/Characteristics/AlphaValues[CharacteristicCode='SIZE']/DiscreteValueAlphanumeric">
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>
<xsl:value-of select = "/SSC/Payload/Item/Characteristics/AlphaValues[CharacteristicCode='SIZE']/DiscreteValueAlphanumeric"/>
</DiscreteValueAlphanumeric>
</AlphaValues>
</xsl:for-each>
</xsl:template>
But this is what i ended up with. All the values were concatenated in each loop
<?xml version="1.0" encoding="UTF-8"?>
<SSC>
<Payload>
<Item>
<Characteristics>
<CharacteristicCode>NRF COLOR</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>NRF COLOR</CharacteristicCode>
<DiscreteValueAlphanumeric>000</DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
<Characteristics>
<CharacteristicCode>SIZE</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>SIZE</CharacteristicCode>
<DiscreteValueAlphanumeric>10</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>SIZE</CharacteristicCode>
<DiscreteValueAlphanumeric>11</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>SIZE</CharacteristicCode>
<DiscreteValueAlphanumeric>12</DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
<Characteristics>
<CharacteristicCode>UPC</CharacteristicCode>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>10 11 12</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>10 11 12</DiscreteValueAlphanumeric>
</AlphaValues>
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>10 11 12</DiscreteValueAlphanumeric>
</AlphaValues>
</Characteristics>
</Item>
</Payload>
</SSC>
Sorry I was trying to simplify my problem previously and didn't realize that it was causing even more problem.
Really appreciate any suggestion!

Try it this way?
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/SSC">
<Characteristics>
<CharacteristicCode>UPC</CharacteristicCode>
<xsl:for-each select="Payload/Item/Characteristics[CharacteristicCode='SIZE']/AlphaValues">
<AlphaValues>
<CharacteristicCode>UPC</CharacteristicCode>
<DiscreteValueAlphanumeric>
<xsl:text>UPC-</xsl:text>
<xsl:value-of select="DiscreteValueAlphanumeric"/>
</DiscreteValueAlphanumeric>
</AlphaValues>
</xsl:for-each>
</Characteristics>
</xsl:template>
</xsl:stylesheet>
Note the relative path used from within xsl:for-each.
Demo: https://xsltfiddle.liberty-development.net/pPJ8LUV

Related

XSLT tranform a SOAP message

Already searched for an answer here, but couldn't find any suitable solution...!
I'm trying to write a XSLT tranformation, starting from a SOAP response message, to be transformed to a XML message (the XML tags will not be the same).
Here is my input SOAP message :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CatalogPriceResponseParams xmlns="http://theurl.com">
<ArrayOfOutputCatalogItems>
<ItemID>003332</ItemID>
<ShipFromPartyWarehouseLocationID>901</ShipFromPartyWarehouseLocationID>
<Quantity>20.0</Quantity>
<UnitCode>PCE</UnitCode>
<UnitPriceAmount>104.9</UnitPriceAmount>
<UnitPricePerQuantity>1.0</UnitPricePerQuantity>
<UnitPricePerQuantityUOM>EA</UnitPricePerQuantityUOM>
<PricingAmountUnitPretaxAmount>104.9</PricingAmountUnitPretaxAmount>
</ArrayOfOutputCatalogItems>
<ArrayOfOutputCatalogItems>
<ItemID>003333</ItemID>
<ShipFromPartyWarehouseLocationID>901</ShipFromPartyWarehouseLocationID>
<Quantity>1.0</Quantity>
<UnitCode>PCE</UnitCode>
<UnitPriceAmount>100.9</UnitPriceAmount>
<UnitPricePerQuantity>1.0</UnitPricePerQuantity>
<UnitPricePerQuantityUOM>EA</UnitPricePerQuantityUOM>
<PricingAmountUnitPretaxAmount>100.9</PricingAmountUnitPretaxAmount>
</ArrayOfOutputCatalogItems>
</CatalogPriceResponseParams>
</soap:Body>
</soap:Envelope>
the desired output is :
<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xsi:noNamespaceSchemaLocation="genericResponse.xsd">
<getPrices>
<errorCode>0</errorCode>
<currency>EUR</currency>
<articleList>
<article>
<articleId>003332</articleId>
<icon>2</icon>
<priceList>
<price>
<price>104.9</price>
</price>
</priceList>
</article>
<article>
<articleId>003333</articleId>
<icon>2</icon>
<priceList>
<price>
<price>100.9</price>
</price>
</priceList>
</article>
</articleList>
</getPrices>
</TradeResponse>
I already started to write a XSLT transformation but this doesn"t give the expected result:
<xsl:stylesheet version="1.0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="soap:*">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="/">
<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="genericResponse.xsd">
<getPrices>
<errorCode>
<xsl:value-of select="'0'"/>
</errorCode>
<currency>
<xsl:value-of select="'EUR'"/>
</currency>
<articleList>
<xsl:for-each select=".*/CatalogPriceResponseParams/ArrayOfOutputCatalogItems">
<article>
<articleId>
<xsl:value-of select="./ItemID"/>
</articleId>
<icon>
<xsl:value-of select="'2'"/>
</icon>
<priceList>
<price>
<price>
<xsl:value-of select="./UnitPriceAmount"/>
</price>
</price>
</priceList>
</article>
</xsl:for-each>
</articleList>
</getPrices>
</TradeResponse>
</xsl:template>
</xsl:stylesheet>
I hacve issue with the for-each instructions and I'm not able to address the XPathes I need.
Any help would be appreciated !
Many Thanks,
David.
As I mentioned in the comments, the main issue here is the default namespace declared in your XSLT. Once you fix that, and remove the unnecessary verbosity, you should be able to do with:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http://theurl.com"
exclude-result-prefixes="soap ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/soap:Envelope">
<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="genericResponse.xsd">
<getPrices>
<errorCode>0</errorCode>
<currency>EUR</currency>
<articleList>
<xsl:for-each select="soap:Body/ns0:CatalogPriceResponseParams/ns0:ArrayOfOutputCatalogItems">
<article>
<articleId>
<xsl:value-of select="ns0:ItemID"/>
</articleId>
<icon>2</icon>
<priceList>
<price>
<price>
<xsl:value-of select="ns0:UnitPriceAmount"/>
</price>
</price>
</priceList>
</article>
</xsl:for-each>
</articleList>
</getPrices>
</TradeResponse>
</xsl:template>
</xsl:stylesheet>

Flat database records to parent Child XML transformation

I have records in database which has same order header with all lines records
Could anybody please help me how to use xsl to transform
<?xml version='1.0' encoding='UTF-8'?>
<getParentChildOutputCollection xmlns="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST/types">
<getParentChildOutput>
<PID>1</PID>
<PNAME>Xerox</PNAME>
<CID>101</CID>
<CNAME>Order 101</CNAME>
<CDESC>Order Paper</CDESC>
</getParentChildOutput>
<getParentChildOutput>
<PID>1</PID>
<PNAME>Xerox</PNAME>
<CID>102</CID>
<CNAME>Order 102</CNAME>
<CDESC>Order Black Ink</CDESC>
</getParentChildOutput>
<getParentChildOutput>
<PID>1</PID>
<PNAME>Xerox</PNAME>
<CID>103</CID>
<CNAME>Order 103</CNAME>
<CDESC>Order Staple Pin</CDESC>
</getParentChildOutput>
<getParentChildOutput>
<PID>2</PID>
<PNAME>HP</PNAME>
<CID>230</CID>
<CNAME>Order 230</CNAME>
<CDESC>Order Red Ink</CDESC>
</getParentChildOutput>
<getParentChildOutput>
<PID>2</PID>
<PNAME>HP</PNAME>
<CID>231</CID>
<CNAME>Order 231</CNAME>
<CDESC>Order Blue Ink</CDESC>
</getParentChildOutput>
</getParentChildOutputCollection>
I want to transform above sml using xsl to below output
<?xml version="1.0" encoding="utf-8"?>
<request-wrapper>
<TransmissionID>1234</TransmissionID>
<DeliveryOrders>
<OrderCode>1</OrderCode>
<Company>Xerox</Company>
<Lines>
<c1d>101</c1d>
<cname>Order 101</cname>
<cdesc>Order Paper</cdesc>
</Lines>
<Lines>
<c1d>102</c1d>
<cname>Order 102</cname>
<cdesc>Order Black Ink</cdesc>
</Lines>
<Lines>
<c1d>3</c1d>
<cname>Order 103</cname>
<cdesc>Order Staple Pin</cdesc>
</Lines>
</DeliveryOrders>
<DeliveryOrders>
<OrderCode>2</OrderCode>
<Company>p2</Company>
<Lines>
<c1d>230</c1d>
<cname>Order 230</cname>
<cdesc>Order Red Ink</cdesc>
</Lines>
<Lines>
<c1d>231</c1d>
<cname>Order 231</cname>
<cdesc>Order Blue Ink</cdesc>
</Lines>
</DeliveryOrders>
</request-wrapper>
I have used the below xsl but in the application I am working it is not working, it is not recognize the key and generate-id commands. Are there any other way I can acheive this?
<?xml version = '1.0' encoding = 'UTF-8'?>
<xsl:stylesheet version="2.0" xml:id="id_1" xmlns:nssrcmpr="http://www.oracle.com/2014/03/ics/schedule" xmlns:nstrgdfl="http://xmlns.oracle.com/cloud/adapter/ftp/writejson/types" xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:nstrgmpr="http://xmlns.oracle.com/cloud/adapter/ftp/writejson_REQUEST/types" xmlns:ora="http://schemas.oracle.com/xpath/extension" xmlns:oracle-xsl-mapper="http://www.oracle.com/xsl/mapper/schemas" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns1="http://xml.oracle.com/adapters/extension" xmlns:ns5="http://xmlns.oracle.com/cloud/adapter/ftp/writejson_REQUEST" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes=" nssrcmpr oraext xsd xp20 ora oracle-xsl-mapper xsi fn ns1 xsl ignore01" xmlns:ignore01="http://www.oracle.com/XSL/Transform/java" ignore01:ignorexmlids="true" xmlns:nsmpr0="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST/types" xmlns:nsmpr1="http://www.oracle.com/2014/03/ic/integration/metadata" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:ns23="http://xmlns.oracle.com/cloud/ftp/write/response/pull" xmlns:flt="http://xmlns.oracle.com/cloud/generic/service/fault" xmlns:dvm="http://www.oracle.com/XSL/Transform/java/com.bea.wli.sb.functions.dvm.DVMFunctions" xmlns:orajs0="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1453381219" xmlns:ns22="http://xml.oracle.com/types" xmlns:orajs6="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1211296200" xmlns:orajs3="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath213937888" xmlns:orajs1="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath562866038" xmlns:orajs7="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath86288" xmlns:tns="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST" xmlns:ns2="http://www.oracle.com/XSL/Transform/java/com.bea.wli.sb.resources.icsxpathfunctions.ICSInstanceTrackingFunctions" xmlns:orajs2="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1600802978" xmlns:orajs5="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath2113524327" xmlns:orajs4="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1290874520" xmlns:ns0="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue">
<oracle-xsl-mapper:schema xml:id="id_2">
<!--SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY.-->
<oracle-xsl-mapper:mapSources xml:id="id_3">
<oracle-xsl-mapper:source type="XSD" xml:id="id_4">
<oracle-xsl-mapper:schema location="../../processor_13/resourcegroup_14/ICSSchedule_1.xsd" xml:id="id_5"/>
<oracle-xsl-mapper:rootElement name="schedule" namespace="http://www.oracle.com/2014/03/ics/schedule" xml:id="id_6"/>
</oracle-xsl-mapper:source>
<oracle-xsl-mapper:source type="WSDL" xml:id="id_13">
<oracle-xsl-mapper:schema location="../../application_27/inbound_28/resourcegroup_29/getParentChild_REQUEST.wsdl" xml:id="id_14"/>
<oracle-xsl-mapper:rootElement name="getParentChildOutputCollection" namespace="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST/types" xml:id="id_15"/>
<oracle-xsl-mapper:param name="getParentChild" xml:id="id_16"/>
</oracle-xsl-mapper:source>
</oracle-xsl-mapper:mapSources>
<oracle-xsl-mapper:mapTargets xml:id="id_7">
<oracle-xsl-mapper:target type="WSDL" xml:id="id_8">
<oracle-xsl-mapper:schema location="../../application_49/inbound_50/resourcegroup_51/writejson_REQUEST.wsdl" xml:id="id_9"/>
<oracle-xsl-mapper:rootElement name="WriteFile" namespace="http://xmlns.oracle.com/cloud/adapter/ftp/writejson_REQUEST/types" xml:id="id_10"/>
</oracle-xsl-mapper:target>
</oracle-xsl-mapper:mapTargets>
<!--GENERATED BY ORACLE XSL MAPPER 12.1.2.0.0-->
</oracle-xsl-mapper:schema>
<!--User Editing allowed BELOW this line - DO NOT DELETE THIS LINE-->
<xsl:param name="getParentChild" xml:id="id_25"/>
<xsl:key name="keyHeader" match="nsmpr0:getParentChildOutput" use="nsmpr0:PID" />
<xsl:key name="keyLines" match="nsmpr0:getParentChildOutput" use="concat(nsmpr0:PID,'#',nsmpr0:CID)" />
<xsl:template match="/" xml:id="id_11">
<nstrgmpr:WriteFile xml:id="id_12">
<nstrgdfl:request-wrapper xml:id="id_31">
<!--<xsl:for-each xml:id="id_33" select="$getParentChild/nsmpr0:getParentChildOutputCollection/nsmpr0:getParentChildOutput">-->
<xsl:for-each xml:id="id_33" select="row[generate-id() = generate-id(key('keyHeader', nsmpr0:PID)[1])]"> <!--Sreejit 1 -->
<nstrgdfl:DeliveryOrders xml:id="id_34">
<nstrgdfl:OrderCode xml:id="id_40">
<xsl:value-of xml:id="id_41" select="nsmpr0:PID"/>
</nstrgdfl:OrderCode>
<nstrgdfl:Company xml:id="id_38">
<xsl:value-of xml:id="id_42" select="nsmpr0:PNAME"/>
</nstrgdfl:Company>
<!-- <xsl:for-each xml:id="id_36" select="."> -->
<xsl:for-each xml:id="id_36" select="key('keyHeader', nsmpr0:PID)[generate-id() = generate-id(key('keyLines', concat(nsmpr0:PID,'#',nsmpr0:CID))[1])]"> <!--Sreejit 2 -->
<nstrgdfl:Lines xml:id="id_37">
<nstrgdfl:c1d xml:id="id_43">
<xsl:value-of xml:id="id_44" select="nsmpr0:CID"/>
</nstrgdfl:c1d>
<nstrgdfl:cname xml:id="id_45">
<xsl:value-of xml:id="id_46" select="nsmpr0:CNAME"/>
</nstrgdfl:cname>
<nstrgdfl:cdesc xml:id="id_47">
<xsl:value-of xml:id="id_48" select="nsmpr0:CDESC"/>
</nstrgdfl:cdesc>
</nstrgdfl:Lines>
</xsl:for-each>
</nstrgdfl:DeliveryOrders>
</xsl:for-each>
</nstrgdfl:request-wrapper>
</nstrgmpr:WriteFile>
</xsl:template>
</xsl:stylesheet>
Regards,
Sree
Your instruction:
<xsl:for-each xml:id="id_33" select="row[generate-id() = generate-id(key('keyHeader', nsmpr0:PID)[1])]">
selects nothing because there is no element named row in the current context (or in the entire input document, for that matter).
Side note: your stylesheet is tagged version="2.0" yet you are attempting to use Muenchian grouping - which makes very little sense.
I pasted the code which worked, just for others in case anybody want the code
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version="2.0" xml:id="id_1" xmlns:nssrcmpr="http://www.oracle.com/2014/03/ics/schedule" xmlns:nstrgdfl="http://xmlns.oracle.com/cloud/adapter/ftp/writejson/types" xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:nstrgmpr="http://xmlns.oracle.com/cloud/adapter/ftp/writejson_REQUEST/types" xmlns:ora="http://schemas.oracle.com/xpath/extension" xmlns:oracle-xsl-mapper="http://www.oracle.com/xsl/mapper/schemas" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns1="http://xml.oracle.com/adapters/extension" xmlns:ns5="http://xmlns.oracle.com/cloud/adapter/ftp/writejson_REQUEST" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes=" nssrcmpr oraext xsd xp20 ora oracle-xsl-mapper xsi fn ns1 xsl ignore01" xmlns:ignore01="http://www.oracle.com/XSL/Transform/java" ignore01:ignorexmlids="true" xmlns:nsmpr0="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST/types" xmlns:nsmpr1="http://www.oracle.com/2014/03/ic/integration/metadata" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:ns23="http://xmlns.oracle.com/cloud/ftp/write/response/pull" xmlns:flt="http://xmlns.oracle.com/cloud/generic/service/fault" xmlns:dvm="http://www.oracle.com/XSL/Transform/java/com.bea.wli.sb.functions.dvm.DVMFunctions" xmlns:orajs0="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1453381219" xmlns:ns22="http://xml.oracle.com/types" xmlns:orajs6="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1211296200" xmlns:orajs3="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath213937888" xmlns:orajs1="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath562866038" xmlns:orajs7="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath86288" xmlns:tns="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST" xmlns:ns2="http://www.oracle.com/XSL/Transform/java/com.bea.wli.sb.resources.icsxpathfunctions.ICSInstanceTrackingFunctions" xmlns:orajs2="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1600802978" xmlns:orajs5="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath2113524327" xmlns:orajs4="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.JsExecutor_xpath1290874520" xmlns:ns0="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue">
<oracle-xsl-mapper:schema xml:id="id_2">
<!--SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY.-->
<oracle-xsl-mapper:mapSources xml:id="id_3">
<oracle-xsl-mapper:source type="XSD" xml:id="id_4">
<oracle-xsl-mapper:schema location="../../processor_13/resourcegroup_14/ICSSchedule_1.xsd" xml:id="id_5"/>
<oracle-xsl-mapper:rootElement name="schedule" namespace="http://www.oracle.com/2014/03/ics/schedule" xml:id="id_6"/>
</oracle-xsl-mapper:source>
<oracle-xsl-mapper:source type="WSDL" xml:id="id_13">
<oracle-xsl-mapper:schema location="../../application_27/inbound_28/resourcegroup_29/getParentChild_REQUEST.wsdl" xml:id="id_14"/>
<oracle-xsl-mapper:rootElement name="getParentChildOutputCollection" namespace="http://xmlns.oracle.com/cloud/adapter/dbaasdatabase/getParentChild_REQUEST/types" xml:id="id_15"/>
<oracle-xsl-mapper:param name="getParentChild" xml:id="id_16"/>
</oracle-xsl-mapper:source>
</oracle-xsl-mapper:mapSources>
<oracle-xsl-mapper:mapTargets xml:id="id_7">
<oracle-xsl-mapper:target type="WSDL" xml:id="id_8">
<oracle-xsl-mapper:schema location="../../application_49/inbound_50/resourcegroup_51/writejson_REQUEST.wsdl" xml:id="id_9"/>
<oracle-xsl-mapper:rootElement name="WriteFile" namespace="http://xmlns.oracle.com/cloud/adapter/ftp/writejson_REQUEST/types" xml:id="id_10"/>
</oracle-xsl-mapper:target>
</oracle-xsl-mapper:mapTargets>
<!--GENERATED BY ORACLE XSL MAPPER 12.1.2.0.0-->
</oracle-xsl-mapper:schema>
<!--User Editing allowed BELOW this line - DO NOT DELETE THIS LINE-->
<xsl:param name="getParentChild" xml:id="id_25"/>
<xsl:output method="xml" version="1.0" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/" xml:id="id_11">
<nstrgmpr:WriteFile xml:id="id_12">
<nstrgdfl:request-wrapper xml:id="id_31">
<xsl:for-each-group xml:id="id_33" select="$getParentChild/nsmpr0:getParentChildOutputCollection/nsmpr0:getParentChildOutput" group-by="nsmpr0:PID">
<nstrgdfl:DeliveryOrders xml:id="id_34">
<nstrgdfl:OrderCode xml:id="id_40">
<xsl:value-of xml:id="id_41" select="nsmpr0:PID"/>
</nstrgdfl:OrderCode>
<nstrgdfl:Company xml:id="id_38">
<xsl:value-of xml:id="id_42" select="nsmpr0:PNAME"/>
</nstrgdfl:Company>
<xsl:for-each select="fn:current-group()">
<nstrgdfl:Lines xml:id="id_37">
<nstrgdfl:c1d xml:id="id_43">
<xsl:value-of xml:id="id_44" select="nsmpr0:CID"/>
</nstrgdfl:c1d>
<nstrgdfl:cname xml:id="id_45">
<xsl:value-of xml:id="id_46" select="nsmpr0:CNAME"/>
</nstrgdfl:cname>
<nstrgdfl:cdesc xml:id="id_47">
<xsl:value-of xml:id="id_48" select="nsmpr0:CDESC"/>
</nstrgdfl:cdesc>
</nstrgdfl:Lines>
</xsl:for-each>
</nstrgdfl:DeliveryOrders>
</xsl:for-each-group>
</nstrgdfl:request-wrapper>
</nstrgmpr:WriteFile>
</xsl:template>
</xsl:stylesheet>

XSL include a non-looping element in a loop

I have an XML-file that looks like this
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="gallring.xsl"?>
<report>
<title>Bibliography</title>
<dateCreated>2016-05-17</dateCreated>
<catalog>
<catalogKey>142343</catalogKey>
<yearOfPublication>1936</yearOfPublication>
<marc>
<marcEntry tag="100" label="Personal Author" ind="1 ">Landelius, Carl</marcEntry>
<marcEntry tag="245" label="Title" ind="00">1840-1850-talets bildningscirklar och arbetareföreningar i Sverige. 1</marcEntry>
</marc>
<call>
<callNumber>374</callNumber>
<library>VALLA</library>
<item>
<dateLastUsed>2009-01-06</dateLastUsed>
</item>
</call>
</catalog>
<catalog>
<catalogKey>661763</catalogKey>
<yearOfPublication>1936</yearOfPublication>
<marc>
<marcEntry tag="100" label="Personal Author" ind="1 ">Landelius, Carl</marcEntry>
<marcEntry tag="245" label="Title" ind="00">1840-1850-talets bildningscirklar och arbetareföreningar i Sverige / Carl Landelius</marcEntry>
</marc>
<call>
<callNumber>374</callNumber>
<library>VALLA</library>
<item>
<dateLastUsed>2014-06-18</dateLastUsed>
</item>
</call>
</catalog>
<catalog>
<catalogKey>32018</catalogKey>
<yearOfPublication>1982</yearOfPublication>
<marc>
<marcEntry tag="245" label="Title" ind="00">ABF-are berättar : minnen från ABF / red.: Allan Malmgren</marcEntry>
</marc>
<call>
<callNumber>374</callNumber>
<library>VALLA</library>
<item>
<dateLastUsed>2008-06-17</dateLastUsed>
</item>
</call>
</catalog>
To open it I use this stylesheet
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<catalog>
<xsl:for-each select="report/catalog">
<itemline>
<callNumber><xsl:text>"</xsl:text><xsl:value-of select="string(call/callNumber)"/><xsl:text>"</xsl:text></callNumber>
<yearOfPublication><xsl:value-of select="yearOfPublication"/></yearOfPublication>
<Author><xsl:value-of select="marc/marcEntry[#tag='100']"/></Author>
<Title><xsl:value-of select="substring(marc/marcEntry[#tag='245'],1,30)"/></Title>
<dateLastUsed><xsl:value-of select="call/item/dateLastUsed"/></dateLastUsed>
</itemline>
</xsl:for-each>
</catalog>
</xsl:template>
</xsl:stylesheet>
Problem is: I want to include the element title/dateCreated after each call/item/dateLastUsed-element so I can make calculations (in Excel) how many days has passed since dateLastUsed when the report was created.
There are different ways to include the dateCreated, e.g. you can add
<dateCreated><xsl:value-of select="../dateCreated"/></dateCreated>
As you are in a for-each loop for every report/catalog, this goes one step up from the current loop and fetches the information from the current report.
If the "real" XML only contains one report like in this example, you could also write
<dateCreated><xsl:value-of select="//report/dateCreated"/></dateCreated>
to target the dateCreated directly from root.

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 1.0: Muenchian grouping does not work

I have the following simplified XML structure:
<?xml version="1.0" encoding="utf-8"?>
<list>
<INVOIC>
<M_INVOIC>
<G_SG25>
<S_LIN>
<id>LIN</id>
<D_1082>1</D_1082>
<C_C212>
<D_7140>7610400271943</D_7140>
<D_7143_3>EN</D_7143_3>
</C_C212>
</S_LIN>
</G_SG25>
<G_SG25>
<S_LIN>
<id>LIN</id>
<D_1082>2</D_1082>
<C_C212>
<D_7140>1234567890123</D_7140>
<D_7143_3>EN</D_7143_3>
</C_C212>
</S_LIN>
</G_SG25>
</M_INVOIC>
</INVOIC>
<INVOIC>
<SALESORDER>
<ET_VBAP>
<item>
<VBELN>0010002695</VBELN>
<POSNR>000010</POSNR>
<MATNR>000000000000400487</MATNR>
<EAN11>1234567890123</EAN11>
</item>
<item>
<VBELN>0010002695</VBELN>
<POSNR>000020</POSNR>
<MATNR>000000000000002054</MATNR>
<EAN11>5012454920549</EAN11>
</item>
<item>
<VBELN>0010002695</VBELN>
<POSNR>000030</POSNR>
<MATNR>000000000000392104</MATNR>
<EAN11>3046920921046</EAN11>
</item>
<item>
<VBELN>0010002695</VBELN>
<POSNR>000040</POSNR>
<MATNR>000000000000859146</MATNR>
<EAN11>8003340591469</EAN11>
</item>
<item>
<VBELN>0010002695</VBELN>
<POSNR>000050</POSNR>
<MATNR>000000000000727194</MATNR>
<EAN11>7610400271943</EAN11>
</item>
</ET_VBAP>
</SALESORDER>
</INVOIC>
</list>
my XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="kByEanPos" match="G_SG25" use="S_LIN/C_C212/D_7140"/>
<xsl:template match="/">
<xsl:variable name="uniqueSet" select="G_SG25[generate-id()=generate-id(key('kByEanPos',S_LIN/C_C212/D_7140))]"/>
<list>
<xsl:for-each select="list/INVOIC/M_INVOIC/G_SG25[generate-id()=
generate-id(key('kByEanPos',S_LIN/C_C212/D_7140))]">
<ean>
<xsl:value-of select="parent::M_INVOIC/parent::INVOIC/parent::list/INVOIC/SALESORDER/ET_VBAP/item/MATNR"/>
</ean>
</xsl:for-each>
</list>
</xsl:template>
</xsl:stylesheet>
gives me this XML output:
<?xml version="1.0" encoding="UTF-8"?>
<list>
<ean>000000000000400487</ean>
<ean>000000000000400487</ean>
</list>
But my expected XML output is:
<?xml version="1.0" encoding="UTF-8"?>
<list>
<ean>000000000000727194</ean>
<ean>000000000000400487</ean>
</list>
I am not sure of what I am doing wrong, I can't find my mistake. I think it has to do with the key that I defined.
Basically I need a key on <D_7140> and then look for that number in the structure below in EAN11 and output the MATNR right before.
In this line:
<xsl:value-of
select="parent::M_INVOIC/parent::INVOIC/parent::list/INVOIC/SALESORDER/ET_VBAP/item/MATNR"/>
You're climbing all the way up the node tree and back down to MATNR, so the only thing this is ever going to find is the first MATNR in the document. To locate the MATNR that corresponds to the current D_7140 in your for-each, this should work:
<xsl:value-of
select="/list/INVOIC/SALESORDER/ET_VBAP/item[EAN11 = current()/S_LIN/C_C212/D_7140]/MATNR"/>
If you are trying to look up item elements based on their EAN11 value, it might be worth considering using a key to do this too
<xsl:key name="item" match="item" use="EAN11" />
That way, you can reduce your xsl:value-of to just this
<xsl:value-of select="key('item', S_LIN/C_C212/D_7140)/MATNR"/>