XSL Grouping not giving any result - xslt
I want to group on "zero:PosNo"
If I remove the group-commands it returns a result, but obviously it returns this:
INSERT INTO RAPP_ADM.MTO_POS_IMP_TAB (PROJECT_NO, MTO_OWNER_NO, POS_NO, PART_NO, DESCRIPTION, QTY, UNIT, TOT_LEN, TOT_WEIGHT, DRAWING, GRADE, TRACE, BI_PRODUCT, SURFACE, CALC, DISCIPLINE, MADE_BY, POS_NO2, PLT_SEQ, OBJECT_SQ, OBJECT_REVISION)
VALUES ('6111', '26-0008-R552-MOD-01-M', '1','PIP03D1160', 'PIPE sch.160 ASTM A790 UNS S31', 2.000, 'M', 2.000, 42.700, 'C097-RWP-L-XN-0057-01', 'sch.160 ASTM A790 UNS S31', 'N', '26-0008-R552-MOD-01-1', 0.559, 'N', 'L', 'sindre.thompson', '', 721, '1556750', '1');
INSERT INTO RAPP_ADM.MTO_POS_IMP_TAB (PROJECT_NO, MTO_OWNER_NO, POS_NO, PART_NO, DESCRIPTION, QTY, UNIT, TOT_LEN, TOT_WEIGHT, DRAWING, GRADE, TRACE, BI_PRODUCT, SURFACE, CALC, DISCIPLINE, MADE_BY, POS_NO2, PLT_SEQ, OBJECT_SQ, OBJECT_REVISION) VALUES
('6111', '26-0008-R552-MOD-01-M', '1','PIP03D1160', 'PIPE sch.160 ASTM A790 UNS S31', 0.660, 'M', 0.660, 14.093, 'C097-RWP-L-XN-0057-01', 'sch.160 ASTM A790 UNS S31', 'N', '26-0008-R552-MOD-01-1', 0.184, 'N', 'L', 'sindre.thompson', '', 721, '1556750', '1');
xmlns:zero="rosenbergverft.com:3D/2011/Zero"
<xsl:output method="text" omit-xml-declaration="yes" standalone="no" media-type="text/plain"/>
<xsl:template match="/">
<xsl:for-each select="/zero:Zero/zero:MTOOwner/zero:DocumentNo/zero:BiProduct/zero:Part">
<xsl:for-each-group select="/" group-by="zero:POS_NO">
<xsl:sort select="zero:PosNo" />
INSERT INTO RAPP_ADM.MTO_POS_IMP_TAB (PROJECT_NO, MTO_OWNER_NO, POS_NO, PART_NO, DESCRIPTION, QTY, UNIT, TOT_LEN, TOT_WEIGHT, DRAWING, GRADE, TRACE, BI_PRODUCT, SURFACE, CALC, DISCIPLINE, MADE_BY, POS_NO2, PLT_SEQ, OBJECT_SQ, OBJECT_REVISION) VALUES ('
<xsl:value-of select="../../../../pdms:PDMSProject/pdms:ProjectNumber/#text" />',
'<xsl:value-of select="zero:MtoOwnerNo" />',
'<xsl:value-of select="zero:PosNo" />',
'<xsl:value-of select="zero:StockNo" />',
'<xsl:value-of select="zero:Description" />',
<xsl:choose>
<xsl:when test="zero:Quantity/#unit = 'mm2'"><xsl:value-of select="format-number(zero:Quantity/#number div 1000000, '#0.000')"/><xsl:text>, 'M2'</xsl:text></xsl:when>
<xsl:when test="zero:Quantity/#unit = 'mm'"><xsl:value-of select="format-number(zero:Quantity/#number div 1000, '#0.000')"/><xsl:text>, 'M'</xsl:text></xsl:when>
<xsl:when test="zero:Quantity/#unit = 'pcs'"><xsl:value-of select="format-number(zero:Quantity/#number, '#0')"/><xsl:text>, 'EA'</xsl:text></xsl:when>
<xsl:otherwise><xsl:value-of select="format-number(zero:Quantity/#number, '#0.000')"/><xsl:text>, ''</xsl:text></xsl:otherwise>
</xsl:choose>,
<xsl:value-of select="format-number(zero:TotalLength/#number div 1000, '#0.000')" />,
<xsl:value-of select="zero:TotalWeight/#number" />,
'<xsl:value-of select="zero:DocumentNo" />', '<xsl:value-of select="zero:Grade" />',
<xsl:choose>
<xsl:when test="zero:Traceable/#boolean = 'false'"><xsl:text>'N'</xsl:text></xsl:when>
<xsl:otherwise><xsl:text>'Y'</xsl:text></xsl:otherwise>
</xsl:choose>,
'<xsl:value-of select="zero:BiProduct" />',
<xsl:value-of select="format-number(zero:Surface/#number div 1000000, '#0.000')" />,
'<xsl:value-of select="zero:Calc" />', '<xsl:value-of select="zero:Discipline" />',
'<xsl:value-of select="zero:Designer" />', '<xsl:value-of select="zero:Name" />',
<xsl:value-of select="../../../zero:PlantSeq/#number" />, '<xsl:value-of select="../../../zero:ObjectSeq/#number" />',
'<xsl:value-of select="../../../zero:ObjectRev" />');
</xsl:for-each-group>
</xsl:for-each>
This is what I want to achieve:
I want the numbers on PosNo 1 to be summarized, so that it returns just one insert for PosNo 1, and not two.
The same for Posno 2, 3 etc.
INSERT INTO RAPP_ADM.MTO_POS_IMP_TAB (PROJECT_NO, MTO_OWNER_NO, POS_NO, PART_NO, DESCRIPTION, QTY, UNIT, TOT_LEN, TOT_WEIGHT, DRAWING, GRADE, TRACE, BI_PRODUCT, SURFACE, CALC, DISCIPLINE, MADE_BY, POS_NO2, PLT_SEQ, OBJECT_SQ, OBJECT_REVISION) VALUES
('6111', '26-0008-R552-MOD-01-M', '1','PIP03D1160', 'PIPE sch.160 ASTM A790 UNS S31', 2.66, 'M', 2.66, 56.793, 'C097-RWP-L-XN-0057-01', 'sch.160 ASTM A790 UNS S31', 'N', '26-0008-R552-MOD-01-1', 0.559, 'N', 'L', 'sindre.thompson', '', 721, '1556750', '1');
I can't figure out what I'm doing wrong. Am I making any obvious mistakes?
I guess instead of
<xsl:for-each select="/zero:Zero/zero:MTOOwner/zero:DocumentNo/zero:BiProduct/zero:Part">
<xsl:for-each-group select="/" group-by="zero:POS_NO">
<xsl:sort select="zero:PosNo" />
you want
<xsl:for-each-group select="/zero:Zero/zero:MTOOwner/zero:DocumentNo/zero:BiProduct/zero:Part" group-by="zero:POS_NO">
<xsl:sort select="current-grouping-key()" />
But is is a guess, show us your input structure and the desired result structure.
<xsl:for-each-group select="/">
has to be wrong, because "/" selects a single node and grouping a single node is never useful.
But without seeing the input XML, it's hard to tell you what you should have written instead.
Related
Date time conversion results in FORG0001 Invalid dateTime value - XSLT 3.0
Resources: Java 1.8 Saxon-HE-10.3 XSLT3.0 I am merging 2 XML files and want to do date manipulation in the merged output file xml. I am taking the 2 files as input using java and generate the merged xml - This works fine. Now, I added the date manipulation in the xsl after the merging operation. Date Manipulation - convert the given date to epoch/milliseconds Date format which comes with the input file <PROP NAME="START_DATE"> <PVAL>16-Aug-2018</PVAL> </PROP> The issue is when I try to convert the given date to dateTime or convert to epoch, I get the below error on compilation. Error at char 10 in expression in xsl:value-of/#select on line 60 column 105 of CASTransform.xsl: FORG0001 Invalid dateTime value "/01--20T00:00:00" (Non-numeric year component) at template reformat-date on line 55 of CASTransform.xsl: invoked by xsl:call-template at file:/home/Merger/scripts/CASTransform.xsl#50 In template rule with match="element(Q{}RECORDS)/element(Q{}RECORD)/element(Q{}PROP)[(Q{http://www.w3.org/2001/XMLSchema}string(data(attribute::attribute(Q{}NAME)))) eq "START_DATE"]/element(Q{}PVAL)" on line 48 of CASTransform.xsl invoked by xsl:apply-templates at file:/home/Merger/scripts/CASTransform.xsl#45 In template rule with match="(element()|(text()|(comment()|processing-instruction())))" on line 43 of CASTransform.xsl invoked by xsl:apply-templates at file:/home/Merger/scripts/CASTransform.xsl#35 at template main on line 14 of CASTransform.xsl: Exception in thread "main" net.sf.saxon.s9api.SaxonApiException: Invalid dateTime value "/01--20T00:00:00" (Non-numeric year component) at net.sf.saxon.s9api.Xslt30Transformer.callTemplate(Xslt30Transformer.java:488) XSL Code <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:array="http://www.w3.org/2005/xpath-functions/array" exclude-result-prefixes="#all"> <xsl:mode on-no-match="shallow-copy"/> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:param name="mapData"/> <xsl:template match="/" name="main"> <RECORDS> <xsl:variable name="file1" select="map:get($mapData, '1')" /> <xsl:variable name="input-doc1" as="document-node()" select="doc($file1)"/> <xsl:variable name="file2" select="map:get($mapData, '2')" /> <xsl:variable name="input-doc2" as="document-node()" select="doc($file2)"/> <xsl:merge> <xsl:merge-source name="doc1" select="$input-doc1/RECORDS/RECORD"> <xsl:merge-key select="PROP[#NAME = 'Id']/PVAL"></xsl:merge-key> </xsl:merge-source> <xsl:merge-source name="doc2" select="$input-doc2/RECORDS/RECORD"> <xsl:merge-key select="PROP[#NAME = 'Id']/PVAL"></xsl:merge-key> </xsl:merge-source> <xsl:merge-action> <xsl:if test="current-merge-group('doc1')"> <xsl:copy> <xsl:apply-templates select="*, current-merge-group('doc2')/(* except PROP[#NAME = 'Id'])"/> </xsl:copy> </xsl:if> </xsl:merge-action> </xsl:merge> </RECORDS> </xsl:template> <xsl:template match="#*|node()"> <xsl:copy> <xsl:apply-templates select="#*|node()" /> </xsl:copy> </xsl:template> <xsl:template match="RECORDS/RECORD/PROP[#NAME = 'START_DATE']/PVAL | RECORDS/RECORD/PROP[#NAME = 'END_DATE']/PVAL"> <xsl:element name="{name()}"> <xsl:call-template name="reformat-date"> <xsl:with-param name="date" select="." /> </xsl:call-template> </xsl:element> </xsl:template> <xsl:template name="reformat-date"> <xsl:param name="date" /> <xsl:variable name="dd" select="substring($date,1,2)" /> <xsl:variable name="mmm" select="upper-case(substring($date,4,3))" /> <xsl:variable name="yyyy" select="substring($date,8,4)" /> <xsl:variable name="mmm"> <xsl:choose> <xsl:when test="$mmm = 'JAN'">01</xsl:when> <xsl:when test="$mmm = 'FEB'">02</xsl:when> <xsl:when test="$mmm = 'MAR'">03</xsl:when> <xsl:when test="$mmm = 'APR'">04</xsl:when> <xsl:when test="$mmm = 'MAY'">05</xsl:when> <xsl:when test="$mmm = 'JUN'">06</xsl:when> <xsl:when test="$mmm = 'JUL'">07</xsl:when> <xsl:when test="$mmm = 'AUG'">08</xsl:when> <xsl:when test="$mmm = 'SEP'">09</xsl:when> <xsl:when test="$mmm = 'OCT'">10</xsl:when> <xsl:when test="$mmm = 'NOV'">11</xsl:when> <xsl:when test="$mmm = 'DEC'">12</xsl:when> </xsl:choose> </xsl:variable> <xsl:variable name="temp1" as="xs:string" select="string-join(($yyyy,$mmm,$dd),'-')" /> <xsl:value-of select="$temp1" /> </xsl:template> </xsl:stylesheet> The above XSL code works perfectly fine and the $temp1 gives proper date like 2018-08-16. Now, when I try to convert this to dateTime variable I get the mentioned compilation error. Code which gives error: <xsl:variable name="temp2" as="xs:dateTime" select="xs:dateTime(concat($temp1,'T00:00:00'))"/> and tried this as well : <xsl:value-of select="floor((xs:dateTime(concat($temp1,'T00:00:00')) - xs:dateTime('1970-01-01T00:00:00')) div xs:dayTimeDuration('PT1S')) "/> Requesting your help as this is my first XSL project. Full Stacktrace: Error at char 10 in expression in xsl:value-of/#select on line 60 column 105 of CASTransform.xsl: FORG0001 Invalid dateTime value "/01--20T00:00:00" (Non-numeric year component) at template reformat-date on line 55 of CASTransform.xsl: invoked by xsl:call-template at file:/home/Merger/scripts/CASTransform.xsl#50 In template rule with match="element(Q{}RECORDS)/element(Q{}RECORD)/element(Q{}PROP)[(Q{http://www.w3.org/2001/XMLSchema}string(data(attribute::attribute(Q{}NAME)))) eq "START_DATE"]/element(Q{}PVAL)" on line 48 of CASTransform.xsl invoked by xsl:apply-templates at file:/home/Merger/scripts/CASTransform.xsl#45 In template rule with match="(element()|(text()|(comment()|processing-instruction())))" on line 43 of CASTransform.xsl invoked by xsl:apply-templates at file:/home/Merger/scripts/CASTransform.xsl#35 at template main on line 14 of CASTransform.xsl: Exception in thread "main" net.sf.saxon.s9api.SaxonApiException: Invalid dateTime value "/01--20T00:00:00" (Non-numeric year component) at net.sf.saxon.s9api.Xslt30Transformer.callTemplate(Xslt30Transformer.java:488) at com.tracer.Merger.CASExportInput.trans(CASExportInput.java:38) at com.tracer.Merger.CASExportInput.main(CASExportInput.java:58) Caused by: ValidationException: Invalid dateTime value "/01--20T00:00:00" (Non-numeric year component) at net.sf.saxon.type.ValidationFailure.makeException(ValidationFailure.java:406) at net.sf.saxon.expr.CastExpression.doCast(CastExpression.java:385) at net.sf.saxon.expr.CastExpression.evaluateItem(CastExpression.java:402) at net.sf.saxon.expr.CastExpression.evaluateItem(CastExpression.java:30) at net.sf.saxon.expr.Expression.iterate(Expression.java:872) at net.sf.saxon.expr.AtomicSequenceConverter.iterate(AtomicSequenceConverter.java:304) at net.sf.saxon.expr.Expression.process(Expression.java:949) at net.sf.saxon.expr.instruct.ValueOf.processLeavingTail(ValueOf.java:340) at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:746) at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:752) at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:264) at net.sf.saxon.expr.instruct.CallTemplate$CallTemplatePackage.processLeavingTail(CallTemplate.java:549) at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:478) at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:351) at net.sf.saxon.expr.instruct.ApplyTemplates.process(ApplyTemplates.java:285) at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:352) at net.sf.saxon.expr.instruct.Copy.processLeavingTail(Copy.java:429) at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:384) at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:568) at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:351) at net.sf.saxon.expr.instruct.ApplyTemplates.process(ApplyTemplates.java:285) at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:352) at net.sf.saxon.expr.instruct.Copy.processLeavingTail(Copy.java:429) at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:142) at net.sf.saxon.expr.parser.ExpressionTool.getIteratorFromProcessMethod(ExpressionTool.java:643) at net.sf.saxon.expr.instruct.Instruction.iterate(Instruction.java:374) at net.sf.saxon.expr.instruct.Choose.iterate(Choose.java:1019) at net.sf.saxon.expr.sort.MergeInstr.lambda$iterate$0(MergeInstr.java:543) at net.sf.saxon.expr.ContextMappingIterator.next(ContextMappingIterator.java:61) at net.sf.saxon.om.SequenceIterator.forEachOrFail(SequenceIterator.java:135) at net.sf.saxon.expr.sort.MergeInstr.processLeavingTail(MergeInstr.java:823) at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:142) at net.sf.saxon.expr.LetExpression.process(LetExpression.java:625) at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:352) at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:298) at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:264) at net.sf.saxon.trans.XsltController.callTemplate(XsltController.java:850) at net.sf.saxon.s9api.Xslt30Transformer.callTemplate(Xslt30Transformer.java:480) ... 2 more Java code which serves the Input files : package com.tracer.Merger.CASMerger; import java.io.File; import java.util.HashMap; import java.util.Map; import javax.xml.transform.stream.StreamSource; import net.sf.saxon.s9api. * ; public class CASExportInput { public static void trans(String XSLFile, String File1, String File2, String OutputFileName, String OutputFilePath) throws SaxonApiException { String MergedFile = OutputFilePath.concat(OutputFileName); Processor processor = new Processor(false); XsltCompiler compiler = processor.newXsltCompiler(); XsltExecutable exp = compiler.compile(new StreamSource(new File(XSLFile))); Serializer out = processor.newSerializer(new File(MergedFile)); out.setOutputProperty(Serializer.Property.METHOD, "xml"); out.setOutputProperty(Serializer.Property.INDENT, "yes"); Xslt30Transformer trans = exp.load30(); Map < String, String > mapData = new HashMap < String, String > (); mapData.put("1", File1); mapData.put("2", File2); HashMap < QName, XdmValue > parameters = new HashMap < >(); parameters.put(new QName("mapData"), XdmMap.makeMap(mapData)); trans.setStylesheetParameters(parameters); trans.callTemplate(new QName("main"), out); System.out.println("Output written to : " + MergedFile); } public static void main(String args[]) throws SaxonApiException { if (args.length < 3) System.out.println("\nPlease check if you have entered arguments properly..."); String XSLFile = args[0].toString().trim(); String File1 = args[1].toString().trim(); String File2 = args[2].toString().trim(); String FileName1 = File1.substring(File1.lastIndexOf("/") + 1, File1.length() - 4); String FileName2 = File2.substring(File2.lastIndexOf("/") + 1, File2.length() - 4); String OutputFilePath = File1.substring(0, File1.lastIndexOf("/") + 1); String OutputFileName = FileName1.concat("-" + FileName2 + ".xml"); trans(XSLFile, File1, File2, OutputFileName, OutputFilePath); } }
Not sure what the issue was. But, I uninstalled and re-installed Java 1.8 and the issue got fixed. No changes were done in the xsl or java code.
XSLT sequence of numbers to range
In XSLT (2.0 preferred), how to convert a sequence of numbers in an array to a range of numbers, eg. <a>1, 2, 3, 6, 7, 9</a> to <a>1-3, 6-7, 9</a>?
You can simply use for-each-group select="$sequence" group-adjacent="xs:integer(.) - position()": <xsl:template match="a"> <xsl:copy> <xsl:value-of separator=", "> <xsl:for-each-group select="tokenize(., ',\s*')" group-adjacent="xs:integer(.) - position()"> <xsl:sequence select=" if (not(current-group()[2])) then . else concat(., '-', current-group()[last()])"/> </xsl:for-each-group> </xsl:value-of> </xsl:copy> </xsl:template> Transforms <a>1, 2, 3, 6, 7, 9</a> into <a>1-3, 6-7, 9</a>
equals not matching though declared
I've the below XML Text S1/7/1 And the below XSLT. <xsl:template match="text()"> <xsl:analyze-string select="." regex="(\w+)/(\w+)/(\w+)"> <xsl:matching-substring> <xsl:variable name="ChpnMatch"> <xsl:value-of select="substring(regex-group(1),1,1)"/> </xsl:variable> <xsl:variable name="regex1"> <xsl:choose> <xsl:when test="$ChpnMatch = 'U'"> <xsl:text>HKWB2015EDSUPP2_CH_S4</xsl:text> </xsl:when> <xsl:when test="$ChpnMatch = 'B|D|E|L|R|F|H|K|Q|S'"> <xsl:text>HKWB2015EDSUPP2_CH_S3</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>HKWB2015EDSUPP2_CH_S1</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:variable> <a href="{concat('er:#',$regex1,'/P',regex-group(1),'-',regex-group(2),'-',regex-group(3))}"> <xsl:value-of select="."/> </a> </xsl:matching-substring> <xsl:non-matching-substring> <xsl:value-of select="."/> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:template> Here there is a case <xsl:when test="$ChpnMatch = 'B|D|E|L|R|F|H|K|Q|S'">, which is the actual match the result should be HKWB2015EDSUPP2_CH_S3, but the result that is caught is HKWB2015EDSUPP2_CH_S1 (which is otherwise block). can you please let me know where am i going wrong and how to fix this. Here is Working Demo Thanks
If you want to compare a string to a sequence of other strings then you need e.g. 'S' = ('A', 'B', 'D', 'S') so I think instead of xsl:when test="$ChpnMatch = 'B|D|E|L|R|F|H|K|Q|S'" you want xsl:when test="$ChpnMatch = ('B', 'D', 'E', 'L', 'R', 'F', 'H', 'K', 'Q', 'S')". That checks whether $ChpnMatch is equal to at least one of the strings in the sequence ('B', 'D', 'E', 'L', 'R', 'F', 'H', 'K', 'Q', 'S').
XSL conversion from 2.0
I have a problem converting XSLT 2.0 to XSLT 3.0. I want to use the streaming capability of XSLT 3.0. I am struggling with using the <xsl:stream> and <xsl:mode> tags as XSLT 3.0 has several restrictions. For using XSLT 3.0 streaming capabilities, following restrictions are faced: “Sibling nodes and ancestor sibling are not reachable”. "You can visit child nodes only once" "You have access only to the current element attributes and namespace declaration" How can I overcome these restrictions? Can anyone please help me? <?xml version="1.0" encoding="UTF-8"> <xsl:stream href="SampleInput3_0.xml"> <xsl:for-each select="copy-of(ns0:ORM_O01/ns0:ORM_O01.PATIENT/ns0:PID)"> <Patient> <ucfd:Name> <xsl:variable name="varFirst_Name" as="node()" select="ns0:PID.5/ns0:XPN.2[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]" /> <xsl:variable name="varLast_Name" as="node()" select="ns0:XPN.1/ns0:FN.1[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]" /> <xsl:attribute name="value" namespace="" select="concat(string($varFirst_Name), string(varLast_Name))" /> </ucfd:Name> <ucfd:FirstName value="{ns0:PID.5/ns0:XPN.2[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:LastName value="{ns0:PID.5/ns0:XPN.1/ns0:FN.1}" /> <ucfd:MiddleName value="{ns0:PID.5/ns0:XPN.3[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Prefix value="{ns0:PID.5/ns0:XPN.5[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Suffix value="{ns0:PID.5/ns0:XPN.4[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Identification> <ucfd:TaxIdentifier> <ucfd:Type value="{ns0:PID.18/ns0:CX.5[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Identifier value="{ns0:PID.18/ns0:CX.1}" /> </ucfd:TaxIdentifier> </ucfd:Identification> <xsl:for-each select="ns0:PID.11"> <ucfd:Address> <xsl:if test="exists(#Type)"> <ucfd:Type value="{ns0:XAD.7[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> </xsl:if> <ucfd:City value="{ns0:XAD.3[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:State value="{ns0:XAD.4[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:PostalCode value="{ns0:XAD.5[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Country value="{ns0:XAD.6[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:County value="{ns0:XAD.9[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> </ucfd:Address> </xsl:for-each> <ucfd:Contact> <ucfd:Role value="{ns0:PID.13/ns0:XTN.2[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Type value="{ns0:PID.13/ns0:XTN.3[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <xsl:for-each select="ns0:PID.13"> <!--<xsl:variable name="var9_current" as="node()" select="."/>--> <ucfd:CommunicationNumber> <xsl:if test="exists(#Type)"> <ucfd:Type> <xsl:sequence select="()" /> </ucfd:Type> </xsl:if> <ucfd:Identifier> <!--<xsl:variable name="var8_current" as="node()" select="ns0:XTN.5[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]"/> <xsl:variable name="var7_current" as="node()" select="ns0:XTN.6[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]"/> <xsl:variable name="var6_current" as="node()" select="ns0:XTN.7[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]"/> <xsl:variable name="var5_current" as="node()" select="ns0:XTN.8[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]"/> <xsl:variable name="var4_current" as="node()" select="ns0:XTN.10[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]"/> <xsl:variable name="var3_current" as="node()" select="ns0:XTN.11[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]"/> <xsl:attribute name="value" namespace="" select="concat(concat(concat(concat(concat(string($var8_current), string($var7_current)), string($var6_current)), string($var5_current)), string($var4_current)), string($var3_current))"/> --> </ucfd:Identifier> </ucfd:CommunicationNumber> </xsl:for-each> </ucfd:Contact> <ucfd:Demographics> <ucfd:BirthDate> <xsl:sequence select="()" /> </ucfd:BirthDate> <ucfd:BirthSequenceNumber> <xsl:for-each select="ns0:ORM_O01/ns0:ORM_O01.PATIENT/ns0:PID/ns0:PID.25"> <xsl:attribute name="value" namespace=""> <xsl:if test="not((translate(string(#xsi:nil), 'true ', '1') = '1'))"> <xsl:sequence select="xs:string(xs:integer(string(.)))" /> </xsl:if> </xsl:attribute> </xsl:for-each> </ucfd:BirthSequenceNumber> <ucfd:DeathDate> <xsl:sequence select="()" /> </ucfd:DeathDate> <ucfd:Gender value="ns0:PID.8[not((translate(string(#xsi:nil), 'true ', '1') = '1'))]" /> <ucfd:MaritalStatus value="{ns0:PID.16/ns0:CE_0002.1[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:CitizenshipStatus value="{ns0:PID.26[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:RaceOrEthnicity> <ucfd:Race value="{ns0:PID.10/ns0:CE_0005.1[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> </ucfd:RaceOrEthnicity> <ucfd:Religion value="{ns0:PID.17/ns0:CE_0006.2[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> </ucfd:Demographics> <ucfd:Language> <ucfd:LanguageCode value="{ns0:PID.15/ns0:CE_0296.1[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:Description value="{ns0:PID.15/ns0:CE_0296.2[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> <ucfd:UseIndicator value="{ns0:PID.15/ns0:CE_0296.3[not(translate(#xsi:nil, 'true ', '1') = '1')]}" /> </ucfd:Language> </Patient> </xsl:for-each> </xsl:stream> </MemberRecord> </xsl:template> </xsl:stylesheet>
I think you should follow the approach in http://saxonica.com/documentation/index.html#!sourcedocs/streaming/burst-mode-streaming so along the lines of <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="..." xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="..." xmlns:ccfd="..." xmlns:hcfd="..." xmlns:ucf="..." xmlns:ucfd="..." exclude-result-prefixes="ns0 xs"> <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/> <!-- start with this named template --> <xsl:template name="main"> <MemberRecord xsi:schemaLocation="..."> <Patient> <xsl:stream href='employees.xml'> <xsl:apply-templates select="copy-of(ns0:ORM_O01/ns0:ORM_O01.PATIENT/ns0:PID)"/> </xsl:stream> </Patient> </MemberRecord> </xsl:template> <xsl:template match="ns0:PID"> <ucfd:Name value="{...}"/> <ucfd:FirstName value="{ns0:PID.5/ns0:XPN.2[not(translate(#xsi:nil, 'true ', '1') = '1'))]}"/> <ucfd:LastName value="{ns0:PID.5/ns0:XPN.1/ns0:FN.1}"/> <!-- compute the other elements and attributes here as above --> </xsl:template> </xsl:stylesheet> That should show the approach, you will have to add code for the remaining elements like middle name and prefix and so on. I have also tried to simplify the compuation of the attribute value in some cases, I think the same can be done for the other cases but I think you should ask that in a different question where you provide details of the XML structure and the values you want to compute, all those nested for-eachs to generate a single value attribute seem a bit convoluted. Also note that I have followed your posted code in creating a single Patient element, I would however expected that a ns0:ORM_O01.PATIENT element is mapped to a Patient so more along the lines of <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="..." xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="..." xmlns:ccfd="..." xmlns:hcfd="..." xmlns:ucf="..." xmlns:ucfd="..." exclude-result-prefixes="ns0 xs"> <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/> <!-- start with this named template --> <xsl:template name="main"> <MemberRecord xsi:schemaLocation="..."> <xsl:stream href='employees.xml'> <xsl:apply-templates select="copy-of(ns0:ORM_O01/ns0:ORM_O01.PATIENT)"/> </xsl:stream> </Patient> </MemberRecord> </xsl:template> <xsl:template match="ns0:ORM_O01.PATIENT"> <Patient> <xsl:apply-templates/> </Patient> </xsl:template> <xsl:template match="ns0:PID"> <ucfd:Name value="{...}"/> <ucfd:FirstName value="{ns0:PID.5/ns0:XPN.2[not(translate(#xsi:nil, 'true ', '1') = '1'))]}"/> <ucfd:LastName value="{ns0:PID.5/ns0:XPN.1/ns0:FN.1}"/> <!-- compute the other elements and attributes here as above --> </xsl:template> </xsl:stylesheet>
Calling function for filtering
This function "karusell:isCurrentDateTimeBetweenDates" never gets called. Why cant i use it for filtering? If a call i alone and store it in a variable it work. The value of the variable is false. <xsl:variable name="bannerList" select="verticaldata/contents/content[ karusell:isCurrentDateTimeBetweenDates( 'Thursday', '01' , 'Friday', '03') ][position() <= 5]" /> Edit: How can the string be returned? The filtering The function <xsl:function name="karusell:isCurrentDateTimeBetweenDates"> <xsl:param name="startDay"/> <xsl:param name="startHour" /> <xsl:param name="endDay"/> <xsl:param name="endHour" /> <xsl:variable name="currentDateTime" select="current-dateTime() " /> <xsl:variable name="todayIndex" select="karusell:getDayIndex(format-dateTime($currentDateTime , '[F]'))" /> <xsl:variable name="startDayIndex" select="karusell:getDayIndex($startDay)" /> <xsl:variable name="endDayIndex" select="karusell:getDayIndex($endDay)" /> <xsl:variable name="startDate" select= "$currentDateTime - ( $todayIndex - $startDayIndex )*xs:dayTimeDuration('P1D')"/> <xsl:variable name="endDate" select= "$currentDateTime + ( $endDayIndex - $todayIndex )*xs:dayTimeDuration('P1D')"/> <xsl:variable name="startDateTime" select="format-dateTime($startDate, concat('[Y0001]-[M01]-[D01]T', $startHour ,':00:00')) cast as xs:dateTime"/> <xsl:variable name="endDateTime" select="format-dateTime($endDate, concat('[Y0001]-[M01]-[D01]T', $endHour ,':00:00')) cast as xs:dateTime"/> <xsl:value-of select="$currentDateTime >= $startDateTime and $currentDateTime < $endDateTime" /> </xsl:function>
Use xsl:sequence, not xsl:value-of to return values of the data type your expression has. So replace <xsl:value-of select="$currentDateTime >= $startDateTime and $currentDateTime < $endDateTime" /> with <xsl:sequence select="$currentDateTime >= $startDateTime and $currentDateTime < $endDateTime" /> Additionally you can get better error diagnosis if you define the return type of your function with <xsl:function name="pf:foo" as="xs:boolean">..</xsl:function>.