You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/09/15 14:43:06 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xslt 3.0 xsl:sequence instruction, along with few new related working test cases.

This is an automated email from the ASF dual-hosted git repository.

mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git


The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
     new f344cee2 committing implementation of xslt 3.0 xsl:sequence instruction, along with few new related working test cases.
     new a9199858 Merge pull request #85 from mukulga/xalan-j_xslt3.0_mukul
f344cee2 is described below

commit f344cee2040514a423f10f4e0ac3d7fe96f3e533
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Fri Sep 15 20:07:52 2023 +0530

    committing implementation of xslt 3.0 xsl:sequence instruction, along with few new related working test cases.
---
 src/org/apache/xalan/processor/XSLTSchema.java     |  19 +-
 src/org/apache/xalan/templates/Constants.java      |   9 +-
 .../apache/xalan/templates/ElemApplyTemplates.java |   2 +-
 src/org/apache/xalan/templates/ElemCopyOf.java     |  34 +-
 src/org/apache/xalan/templates/ElemFunction.java   | 174 +++++++-
 src/org/apache/xalan/templates/ElemSequence.java   | 483 +++++++++++++++++++++
 src/org/apache/xalan/templates/ElemTemplate.java   |   2 +-
 src/org/apache/xalan/templates/ElemVariable.java   |  48 +-
 src/org/apache/xpath/compiler/XPathParser.java     |   2 +-
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   2 +-
 .../apache/xalan/xslt3/XslSequenceInstTests.java   | 103 +++++
 tests/xsl_sequence_inst/gold/test1.out             |   1 +
 tests/xsl_sequence_inst/gold/test2.out             |   1 +
 tests/xsl_sequence_inst/gold/test3.out             |   1 +
 tests/xsl_sequence_inst/gold/test4.out             |   1 +
 tests/xsl_sequence_inst/gold/test5.out             |   6 +
 tests/xsl_sequence_inst/test1.xsl                  |  45 ++
 tests/xsl_sequence_inst/test1_a.xml                |  22 +
 tests/xsl_sequence_inst/test2.xsl                  |  55 +++
 tests/xsl_sequence_inst/test3.xsl                  |  46 ++
 tests/xsl_sequence_inst/test4.xsl                  |  42 ++
 tests/xsl_sequence_inst/test5.xsl                  |  53 +++
 22 files changed, 1101 insertions(+), 50 deletions(-)

diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index 8e3a9816..afca93ab 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -54,6 +54,7 @@ import org.apache.xalan.templates.ElemNumber;
 import org.apache.xalan.templates.ElemOtherwise;
 import org.apache.xalan.templates.ElemPI;
 import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemSequence;
 import org.apache.xalan.templates.ElemSort;
 import org.apache.xalan.templates.ElemTemplate;
 import org.apache.xalan.templates.ElemText;
@@ -244,7 +245,7 @@ public class XSLTSchema extends XSLTElementDef
                                                   XSLTAttributeDef.T_EXPR, false, false, XSLTAttributeDef.ERROR);
 
     // Optional.                                          
-    // xsl:variable, xsl:param, xsl:with-param, xsl:attribute, xsl:break, xsl:on-completion                                       
+    // xsl:variable, xsl:param, xsl:with-param, xsl:attribute, xsl:break, xsl:on-completion, xsl:sequence                                       
     XSLTAttributeDef selectAttrOpt = new XSLTAttributeDef(null, "select",
                                        XSLTAttributeDef.T_EXPR, false, false, XSLTAttributeDef.ERROR);
     
@@ -394,11 +395,11 @@ public class XSLTSchema extends XSLTElementDef
       new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "*",
                            XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.WARNING);
                            
-    XSLTElementDef[] templateElements = new XSLTElementDef[31];
-    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[32];
-    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[32];
+    XSLTElementDef[] templateElements = new XSLTElementDef[32];
+    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[33];
+    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[33];
     //exslt
-    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[32];
+    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[33];
     
     XSLTElementDef[] charTemplateElements = new XSLTElementDef[16];
     XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
@@ -605,6 +606,13 @@ public class XSLTSchema extends XSLTElementDef
                                                            selectAttrOpt, asAttrOpt }, 
                                   new ProcessorTemplateElem(),
                                    ElemVariable.class /* class object */, 20, true);
+    XSLTElementDef xslSequence = new XSLTElementDef(this,
+                                                 Constants.S_XSLNAMESPACEURL, "sequence",
+                                                 null /*alias */,
+                                                 templateElements /* elements */,  // %template;>
+                                                 new XSLTAttributeDef[]{ selectAttrOpt }, 
+                                                 new ProcessorTemplateElem(),
+                                                 ElemSequence.class /* class object */, 20, true);
     XSLTElementDef xslParam = new XSLTElementDef(this,
                                 Constants.S_XSLNAMESPACEURL, "param",
                                 null /*alias */,
@@ -714,6 +722,7 @@ public class XSLTSchema extends XSLTElementDef
     templateElements[i++] = xslText;
     templateElements[i++] = xslCopy;
     templateElements[i++] = xslVariable;
+    templateElements[i++] = xslSequence;
     templateElements[i++] = xslMessage;
     templateElements[i++] = xslFallback;
 
diff --git a/src/org/apache/xalan/templates/Constants.java b/src/org/apache/xalan/templates/Constants.java
index eccca64a..95d273db 100644
--- a/src/org/apache/xalan/templates/Constants.java
+++ b/src/org/apache/xalan/templates/Constants.java
@@ -104,9 +104,11 @@ public class Constants extends org.apache.xml.utils.Constants
   
   ELEMNAME_ITERATE_BREAK = 97,
   
-  ELEMNAME_FUNCTION = 98;
+  ELEMNAME_FUNCTION = 98,
   
-  // next available number : 99
+  ELEMNAME_SEQUENCE = 99;
+  
+  // next available number : 100
 
   /**
    * Literals for XSL element names. Note that there are more
@@ -188,7 +190,8 @@ public class Constants extends org.apache.xml.utils.Constants
       ELEMNAME_VARIABLE_STRING = "variable",
       ELEMNAME_WHEN_STRING = "when",
       ELEMNAME_WITHPARAM_STRING = "with-param",
-      ELEMNAME_FUNCTION_STRING = "function";
+      ELEMNAME_FUNCTION_STRING = "function",
+      ELEMNAME_SEQUENCE_STRING = "sequence";
   
   /**
    * Literals for EXSLT function elements.
diff --git a/src/org/apache/xalan/templates/ElemApplyTemplates.java b/src/org/apache/xalan/templates/ElemApplyTemplates.java
index 884c8536..18335495 100644
--- a/src/org/apache/xalan/templates/ElemApplyTemplates.java
+++ b/src/org/apache/xalan/templates/ElemApplyTemplates.java
@@ -420,7 +420,7 @@ public class ElemApplyTemplates extends ElemCallTemplate
                         }
                         else {
                            ElemCopyOf.copyOfActionOnResultSequence((ResultSequence)templateEvalResultForAsAttr, 
-                                                                                                            transformer, handler, xctxt); 
+                                                                                                            transformer, handler, xctxt, false); 
                         }
                     } 
                     catch (TransformerException ex) {
diff --git a/src/org/apache/xalan/templates/ElemCopyOf.java b/src/org/apache/xalan/templates/ElemCopyOf.java
index 7deb8502..e2de4b8d 100644
--- a/src/org/apache/xalan/templates/ElemCopyOf.java
+++ b/src/org/apache/xalan/templates/ElemCopyOf.java
@@ -73,7 +73,7 @@ public class ElemCopyOf extends ElemTemplateElement
   private Vector fVars;    
   private int fGlobalsSize;
   
-  private final static char SPACE_CHAR = ' ';
+  public final static char SPACE_CHAR = ' ';
 
   /**
    * Set the "select" attribute.
@@ -197,7 +197,7 @@ public class ElemCopyOf extends ElemTemplateElement
                   break;
                 case XObject.CLASS_RESULT_SEQUENCE :         
                   ResultSequence resultSequence = (ResultSequence)value;          
-                  copyOfActionOnResultSequence(resultSequence, transformer, handler, xctxt);          
+                  copyOfActionOnResultSequence(resultSequence, transformer, handler, xctxt, false);          
                   break;
                 default :
                   // no op
@@ -293,8 +293,8 @@ public class ElemCopyOf extends ElemTemplateElement
    * Method to perform xsl:copy-of instruction's action, on an ResultSequence object.
    */
   public static void copyOfActionOnResultSequence(ResultSequence resultSequence, TransformerImpl transformer, 
-                                                                      SerializationHandler serializationHandler, 
-                                                                                       XPathContext xctxt) throws TransformerException, SAXException {
+                                                  SerializationHandler serializationHandler, 
+                                                  XPathContext xctxt, boolean xslSeqProc) throws TransformerException, SAXException {
       char[] spaceCharArr = new char[1];      
       spaceCharArr[0] = SPACE_CHAR;
       
@@ -305,23 +305,35 @@ public class ElemCopyOf extends ElemTemplateElement
          
          if ((xdmItem instanceof XBoolean) || (xdmItem instanceof XNumber) || (xdmItem instanceof XString)) {
              strVal = xdmItem.str();
-             serializationHandler.characters(strVal.toCharArray(), 0, strVal.length());
-             if (idx < (resultSequence.size() - 1)) {                     
-                serializationHandler.characters(spaceCharArr, 0, 1);
+             if (xslSeqProc) {
+                 strVal = strVal + ElemSequence.STRING_VAL_SERIALIZATION_SUFFIX;
+                 serializationHandler.characters(strVal.toCharArray(), 0, strVal.length());
+             }
+             else {
+                 serializationHandler.characters(strVal.toCharArray(), 0, strVal.length());
+                 if (idx < (resultSequence.size() - 1)) {                     
+                    serializationHandler.characters(spaceCharArr, 0, 1);
+                 } 
              }
          }
          else if (xdmItem instanceof XSAnyAtomicType) {
             strVal = ((XSAnyAtomicType)xdmItem).stringValue();
-            serializationHandler.characters(strVal.toCharArray(), 0, strVal.length());
-            if (idx < (resultSequence.size() - 1)) {                     
-               serializationHandler.characters(spaceCharArr, 0, 1);
+            if (xslSeqProc) {
+                strVal = strVal + ElemSequence.STRING_VAL_SERIALIZATION_SUFFIX;
+                serializationHandler.characters(strVal.toCharArray(), 0, strVal.length());
+            }
+            else {
+                serializationHandler.characters(strVal.toCharArray(), 0, strVal.length());
+                if (idx < (resultSequence.size() - 1)) {                     
+                   serializationHandler.characters(spaceCharArr, 0, 1);
+                }
             }
          }
          else if (xdmItem.getType() == XObject.CLASS_NODESET) {                 
              copyOfActionOnNodeSet((XNodeSet)xdmItem, transformer, serializationHandler, xctxt);
          }
          else if (xdmItem.getType() == XObject.CLASS_RESULT_SEQUENCE) {                 
-             copyOfActionOnResultSequence((ResultSequence)xdmItem, transformer, serializationHandler, xctxt);
+             copyOfActionOnResultSequence((ResultSequence)xdmItem, transformer, serializationHandler, xctxt, xslSeqProc);
          }
       } 
   }
diff --git a/src/org/apache/xalan/templates/ElemFunction.java b/src/org/apache/xalan/templates/ElemFunction.java
index 8b297702..21834aa3 100644
--- a/src/org/apache/xalan/templates/ElemFunction.java
+++ b/src/org/apache/xalan/templates/ElemFunction.java
@@ -22,16 +22,34 @@ import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.ref.DTMNodeList;
 import org.apache.xml.utils.QName;
 import org.apache.xpath.VariableStack;
+import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.composite.SequenceTypeData;
 import org.apache.xpath.composite.SequenceTypeSupport;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNodeSetForDOM;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.xs.types.XSBoolean;
+import org.apache.xpath.xs.types.XSDate;
+import org.apache.xpath.xs.types.XSDateTime;
+import org.apache.xpath.xs.types.XSDayTimeDuration;
+import org.apache.xpath.xs.types.XSDecimal;
+import org.apache.xpath.xs.types.XSDouble;
+import org.apache.xpath.xs.types.XSDuration;
+import org.apache.xpath.xs.types.XSFloat;
+import org.apache.xpath.xs.types.XSInt;
+import org.apache.xpath.xs.types.XSInteger;
+import org.apache.xpath.xs.types.XSLong;
+import org.apache.xpath.xs.types.XSString;
+import org.apache.xpath.xs.types.XSYearMonthDuration;
+import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
 
 /**
  * Implementation of XSLT xsl:function element.
@@ -127,7 +145,7 @@ public class ElemFunction extends ElemTemplate
       int paramCount = 0;
       for (ElemTemplateElement elem = getFirstChildElem(); elem != null; 
                                                               elem = elem.getNextSiblingElem()) {
-          if(elem.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) {
+          if (elem.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) {
              if (argSequence.size() < (paramCount + 1)) {
                  throw new TransformerException("XPST0017 : Cannot find a " + argSequence.size() + " argument function named "
                                                                             + "{" + funcNameSpaceUri + "}" + funcLocalName + "() within a stylesheet scope. "
@@ -175,24 +193,29 @@ public class ElemFunction extends ElemTemplate
       NodeList nodeList = (new XRTreeFrag(df, xctxt, this)).convertToNodeset();     
       
       result = new XNodeSetForDOM(nodeList, xctxt);
-            
+                        
       XObject funcResultConvertedVal = result;
       
       String funcAsAttrStrVal = getAs();
       
-      if (funcAsAttrStrVal != null) {
+      if (funcAsAttrStrVal != null) {         
          try {
-            funcResultConvertedVal = SequenceTypeSupport.convertXDMValueToAnotherType(result, funcAsAttrStrVal, null, xctxt);
+            funcResultConvertedVal = preprocessXslFunctionOrAVariableResult((XNodeSetForDOM)result, funcAsAttrStrVal, xctxt);
+            
             if (funcResultConvertedVal == null) {
-               throw new TransformerException("XPTY0004 : The function call result for function {" + funcNameSpaceUri + "}" + funcLocalName + 
-                                                                                "(), doesn't match the declared function result type " + 
-                                                                                                                       funcAsAttrStrVal + ".", srcLocator);   
+                funcResultConvertedVal = SequenceTypeSupport.convertXDMValueToAnotherType(result, funcAsAttrStrVal, null, xctxt);
+                
+                if (funcResultConvertedVal == null) {
+                   throw new TransformerException("XPTY0004 : The function call result for function {" + funcNameSpaceUri + "}" + funcLocalName + 
+                                                                                    "(), doesn't match the declared function result type " + 
+                                                                                                                                  funcAsAttrStrVal + ".", srcLocator);   
+                }
             }
          }
          catch (TransformerException ex) {
             throw new TransformerException("XPTY0004 : The function call result for function {" + funcNameSpaceUri + "}" + funcLocalName + 
                                                                                            "(), doesn't match the declared function result type " + 
-                                                                                                                       funcAsAttrStrVal + ".", srcLocator); 
+                                                                                                                                         funcAsAttrStrVal + ".", srcLocator); 
          }
       }
       
@@ -251,5 +274,140 @@ public class ElemFunction extends ElemTemplate
   {
       root.recomposeTemplates(this);
   }
+  
+  /**
+   * This method helps us solve, XSLT's xsl:function and xsl:variable instruction use cases,
+   * where the XSL child contents of xsl:function or xsl:variable instructions contain 
+   * xsl:sequence instruction(s).
+   * 
+   * Given an initial result of computation of, XSL child contents of a xsl:function or xsl:variable
+   * instructions, and the function's or variable's expected data type, cast an input data
+   * value to the supplied expected data type.
+   */
+  public static ResultSequence preprocessXslFunctionOrAVariableResult(XNodeSetForDOM xNodeSetForDOM,
+                                                                      String sequenceTypeXPathExprStr,
+                                                                      XPathContext xctxt) throws TransformerException {
+     ResultSequence resultSequence = null;
+     
+     DTMNodeList dtmNodeList = (DTMNodeList)(xNodeSetForDOM.object());
+     
+     final int contextNode = xctxt.getContextNode(); 
+     SourceLocator srcLocator = xctxt.getSAXLocator(); 
+     
+     XPath seqTypeXPath = new XPath(sequenceTypeXPathExprStr, srcLocator, 
+                                                                       xctxt.getNamespaceContext(), XPath.SELECT, null, true);
+
+     XObject seqTypeExpressionEvalResult = seqTypeXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
+
+     SequenceTypeData seqExpectedTypeData = (SequenceTypeData)seqTypeExpressionEvalResult;
+
+     Node localRootNode = dtmNodeList.item(0);
+     NodeList nodeList = localRootNode.getChildNodes();
+     int nodeSetLen = nodeList.getLength();
+     
+     if (nodeSetLen == 1) {
+        Node node = nodeList.item(0);
+        short nodeType = node.getNodeType();
+        if (nodeType == Node.TEXT_NODE) {
+             String strVal = ((Text)node).getNodeValue();             
+             if (seqExpectedTypeData.getSequenceTypeKindTest() == null) {               
+                  resultSequence = new ResultSequence();               
+                  if ((seqExpectedTypeData.getItemTypeOccurrenceIndicator() == 0) || 
+                                                                       (seqExpectedTypeData.getItemTypeOccurrenceIndicator() == 
+                                                                                                                SequenceTypeSupport.OccurenceIndicator.ZERO_OR_ONE)) {
+                     if (strVal.contains(ElemSequence.STRING_VAL_SERIALIZATION_SUFFIX)) {
+                         strVal = strVal.replaceAll(ElemSequence.STRING_VAL_SERIALIZATION_SUFFIX, ""); 
+                         XObject xObject = getXSTypedAtomicValue(strVal, seqExpectedTypeData.getSequenceType());
+                         if (xObject != null) {
+                            resultSequence.add(xObject);
+                         }
+                     }
+                     else {
+                         XObject xObject = getXSTypedAtomicValue(strVal, seqExpectedTypeData.getSequenceType());
+                         if (xObject != null) {
+                            resultSequence.add(xObject);
+                         }
+                     }
+                 }
+                 else {
+                     if (strVal.contains(ElemSequence.STRING_VAL_SERIALIZATION_SUFFIX)) {
+                         String[] strParts = strVal.split(ElemSequence.STRING_VAL_SERIALIZATION_SUFFIX);
+                         for (int idx = 0; idx < strParts.length; idx++) {
+                            String seqItemStrVal = strParts[idx];
+                            XObject xObject = getXSTypedAtomicValue(seqItemStrVal, seqExpectedTypeData.getSequenceType());
+                            if (xObject != null) {
+                               resultSequence.add(xObject);
+                            }
+                         }
+                     }
+                     else {
+                         XObject xObject = getXSTypedAtomicValue(strVal, seqExpectedTypeData.getSequenceType());
+                         if (xObject != null) {
+                            resultSequence.add(xObject);
+                         }
+                     } 
+                 }
+             }
+         }
+     }     
+     
+     return resultSequence;
+  }
+  
+  /**
+   * Given XalanJ's integer code value of, an XML Schema built-in data type and a 
+   * string representation of a data value, construct XalanJ's typed data object 
+   * corresponding to the data type's integer code value. 
+   */
+  private static XObject getXSTypedAtomicValue(String strVal, int sequenceType) throws TransformerException {
+      
+      XObject result = null;
+     
+      if (sequenceType == SequenceTypeSupport.BOOLEAN) {
+         boolean boolVal = ("false".equals(strVal) || "0".equals(strVal)) ? false : true;
+         result = new XSBoolean(boolVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.STRING) {
+         result = new XSString(strVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_DATE) {
+         result = XSDate.parseDate(strVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_DATETIME) {
+         result = XSDateTime.parseDateTime(strVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_TIME) {
+         // TO DO
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_DURATION) {
+         result = XSDuration.parseDuration(strVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_DAYTIME_DURATION) {
+         result = XSDayTimeDuration.parseDayTimeDuration(strVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_YEARMONTH_DURATION) {
+         result = XSYearMonthDuration.parseYearMonthDuration(strVal); 
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_DECIMAL) {
+         result = new XSDecimal(strVal); 
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_INTEGER) {
+         result = new XSInteger(strVal); 
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_LONG) {
+         result = new XSLong(strVal);
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_INT) {
+         result = new XSInt(strVal); 
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_DOUBLE) {
+         result = new XSDouble(strVal); 
+      }
+      else if (sequenceType == SequenceTypeSupport.XS_FLOAT) {
+         result = new XSFloat(strVal); 
+      }
+     
+      return result;
+  }
 
 }
diff --git a/src/org/apache/xalan/templates/ElemSequence.java b/src/org/apache/xalan/templates/ElemSequence.java
new file mode 100644
index 00000000..3a60d150
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemSequence.java
@@ -0,0 +1,483 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.templates;
+
+import java.util.List;
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.serialize.SerializerUtils;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.LocPathIterator;
+import org.apache.xpath.axes.SelfIteratorNoPredicate;
+import org.apache.xpath.compiler.XPathParser;
+import org.apache.xpath.composite.SequenceTypeData;
+import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.objects.InlineFunction;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XNodeSetForDOM;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.operations.Operation;
+import org.apache.xpath.operations.Range;
+import org.apache.xpath.operations.SimpleMapOperator;
+import org.apache.xpath.xs.types.XSAnyAtomicType;
+import org.apache.xpath.xs.types.XSNumericType;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.sun.org.apache.xml.internal.dtm.DTM;
+
+/**
+ * Implementation of XSLT xsl:sequence element.
+ * 
+ * Ref : https://www.w3.org/TR/xslt-30/#element-sequence
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class ElemSequence extends ElemTemplateElement
+{
+
+  private static final long serialVersionUID = 4299774714317634314L;
+
+  /**
+   * Constructor ElemSequence
+   */
+  public ElemSequence(){}
+  
+  // The following two fields of this class, are used during 
+  // XPath.fixupVariables(..) action as performed within object of 
+  // this class.    
+  private Vector fVars;    
+  private int fGlobalsSize;
+
+  /**
+   * The value of the "select" attribute.
+   */
+  private XPath m_selectPattern;
+  
+  /**
+   * We use this string value constant to add as a suffix to, a string value that
+   * is getting serialized by XalanJ serializer, when XSL serialization is
+   * getting done during evaluation of xsl:sequence instruction. This helps us
+   * construct later during XSL transformation process, a sequence of XDM atomic
+   * values.
+   * 
+   * We're assuming that, this string value is significantly random, and is unlikely
+   * to exist within an input document that is getting transformed by XalanJ.
+   */
+  public static String STRING_VAL_SERIALIZATION_SUFFIX = "XSL_SEQ" + ElemCopyOf.SPACE_CHAR + "XSL_SEQ";
+
+  /**
+   * Set the value of "select" attribute.
+   *
+   * @param v  Value to set for the "select" attribute.
+   */
+  public void setSelect(XPath v) {
+      m_selectPattern = v;
+  }
+
+  /**
+   * Get the value of "select" attribute.
+   * 
+   * @return Value of the "select" attribute.
+   */
+  public XPath getSelect() {
+     return m_selectPattern;
+  }
+
+  /**
+   * Get an integer representation of the element type.
+   *
+   * @return An integer representation of the element, defined in the
+   *         Constants class.
+   */
+  public int getXSLToken() {
+      return Constants.ELEMNAME_SEQUENCE;
+  }
+
+  /**
+   * Return the node name.
+   *
+   * @return The node name
+   */
+  public String getNodeName() {
+      return Constants.ELEMNAME_SEQUENCE_STRING;
+  }
+
+  /**
+   * @param transformer non-null reference to the the current transform-time state.
+   *
+   * @throws TransformerException
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException {
+
+      int sourceNode = transformer.getXPathContext().getCurrentNode();
+  
+      processXslSequence(transformer, sourceNode);       
+  }
+
+  /**
+   * This method, helps to evaluate an xsl:sequence instruction.
+   * 
+   * @param transformer non-null reference to the the current transform-time state.
+   * @param sourceNode non-null reference to the current source node.
+   *
+   * @throws TransformerException
+   */
+  public void processXslSequence(TransformerImpl transformer, int sourceNode) 
+                                                                           throws TransformerException
+  {
+
+    XObject xslSequenceVal = null;
+    
+    final XPathContext xctxtOriginal = transformer.getXPathContext();
+    
+    XPathContext xctxt = transformer.getXPathContext();
+
+    xctxt.pushCurrentNode(sourceNode);
+    
+    SourceLocator srcLocator = xctxt.getSAXLocator();
+    
+    Expression selectExpression = null;
+ 
+    try {        
+      if (m_selectPattern != null) {          
+        selectExpression = m_selectPattern.getExpression();
+        
+        if (selectExpression instanceof FuncExtFunction) {
+            XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, 
+                                                                                                selectExpression, transformer);
+            if (evalResult != null) {
+               xslSequenceVal = evalResult;    
+            }
+            else {
+               xslSequenceVal = m_selectPattern.execute(xctxt, sourceNode, this);    
+            }            
+        }
+        else if ((selectExpression instanceof Function) || 
+                                                     (selectExpression instanceof SimpleMapOperator) || 
+                                                     (selectExpression instanceof Range)) {
+            xslSequenceVal = selectExpression.execute(xctxt);
+        }
+        else if (selectExpression instanceof Operation) {
+            Operation opn = (Operation)selectExpression;
+            XObject leftOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
+                                                                                           xctxt, opn.getLeftOperand(), transformer);
+            XObject rightOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
+                                                                                           xctxt, opn.getRightOperand(), transformer);
+            xslSequenceVal = opn.operate(leftOperand, rightOperand);
+        }
+        else if (selectExpression instanceof SelfIteratorNoPredicate) {
+            xslSequenceVal = xctxt.getXPath3ContextItem();
+        }
+        else if (selectExpression instanceof LocPathIterator) {                        
+            int contextNode = xctxt.getContextNode();
+            
+            LocPathIterator locPathIterator = (LocPathIterator)selectExpression;
+            
+            DTMIterator dtmIter = null;                     
+            try {
+                dtmIter = locPathIterator.asIterator(xctxt, contextNode);
+            }
+            catch (ClassCastException ex) {
+                // no op
+            }
+            
+            if (dtmIter != null) {               
+               xslSequenceVal = new XNodeSet(dtmIter);
+            }
+            else {
+               ResultSequence resultSeq = new ResultSequence();
+                
+               String xpathExprStr = m_selectPattern.getPatternString();
+               
+               if (xpathExprStr.startsWith("$") && xpathExprStr.contains("[") && 
+                                                                       xpathExprStr.endsWith("]")) {
+                   ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
+                   List<XMLNSDecl> prefixTable = null;
+                   if (elemTemplateElement != null) {
+                       prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
+                   }                                      
+                   
+                   String varRefXPathExprStr = "$" + xpathExprStr.substring(1, xpathExprStr.indexOf('['));
+                   String xpathIndexExprStr = xpathExprStr.substring(xpathExprStr.indexOf('[') + 1, 
+                                                                                        xpathExprStr.indexOf(']'));
+
+                   // Evaluate the, variable reference XPath expression
+                   if (prefixTable != null) {
+                       varRefXPathExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
+                                                                                                          varRefXPathExprStr, 
+                                                                                                          prefixTable);
+                   }                                      
+
+                   XPath varXPathObj = new XPath(varRefXPathExprStr, srcLocator, xctxt.getNamespaceContext(), 
+                                                                                                         XPath.SELECT, null);
+                   if (fVars != null) {
+                      varXPathObj.fixupVariables(fVars, fGlobalsSize);  
+                   }
+                   
+                   XObject varEvalResult = varXPathObj.execute(xctxt, xctxt.getCurrentNode(), xctxt.getNamespaceContext());
+
+                   // Evaluate the, xdm sequence index XPath expression
+                   if (prefixTable != null) {
+                       xpathIndexExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
+                                                                                                         xpathIndexExprStr, 
+                                                                                                         prefixTable);
+                   }
+
+                   XPath xpathIndexObj = new XPath(xpathIndexExprStr, srcLocator, xctxt.getNamespaceContext(), 
+                                                                                                          XPath.SELECT, null);
+                   
+                   if (fVars != null) {
+                      xpathIndexObj.fixupVariables(fVars, fGlobalsSize);  
+                   }
+                   
+                   XObject seqIndexEvalResult = xpathIndexObj.execute(xctxt, xctxt.getCurrentNode(), 
+                                                                                                xctxt.getNamespaceContext());
+
+                   if (varEvalResult instanceof ResultSequence) {
+                       ResultSequence varEvalResultSeq = (ResultSequence)varEvalResult; 
+
+                       if (seqIndexEvalResult instanceof XNumber) {
+                           double dValIndex = ((XNumber)seqIndexEvalResult).num();
+                           if (dValIndex == (int)dValIndex) {
+                               XObject evalResult = varEvalResultSeq.item((int)dValIndex - 1);
+                               resultSeq.add(evalResult);
+                           }
+                           else {
+                               throw new javax.xml.transform.TransformerException("XPTY0004 : an index value used with an xdm "
+                                                                                                               + "sequence reference, is not an integer.", srcLocator); 
+                           }
+                       }
+                       else if (seqIndexEvalResult instanceof XSNumericType) {
+                           String indexStrVal = ((XSNumericType)seqIndexEvalResult).stringValue();
+                           double dValIndex = (Double.valueOf(indexStrVal)).doubleValue();
+                           if (dValIndex == (int)dValIndex) {
+                               XObject evalResult = varEvalResultSeq.item((int)dValIndex - 1);
+                               resultSeq.add(evalResult);
+                           }
+                           else {
+                               throw new javax.xml.transform.TransformerException("XPTY0004 : an index value used with an xdm "
+                                                                                                               + "sequence reference, is not an integer.", srcLocator);  
+                           }
+                       }
+                       else {
+                           throw new javax.xml.transform.TransformerException("XPTY0004 : an index value used with an xdm sequence "
+                                                                                                               + "reference, is not numeric.", srcLocator);   
+                       }
+                   }
+               }
+               
+               xslSequenceVal = resultSeq;
+            }
+        }
+  
+        if (xslSequenceVal == null) {
+           xslSequenceVal = m_selectPattern.execute(xctxt, sourceNode, this);
+        }        
+      }
+      else if (getFirstChildElem() == null) {
+         xslSequenceVal = XString.EMPTYSTRING;
+      }
+      else {
+   		 int sequenceConstructDtmHandle = transformer.transformToRTF(this);
+		 NodeList nodeList = (new XRTreeFrag(sequenceConstructDtmHandle, xctxt, this)).convertToNodeset();		
+		 xslSequenceVal = new XNodeSetForDOM(nodeList, xctxt); 
+      }
+      
+      if (xslSequenceVal == null) {
+          // The result of evaluation of xsl:sequence instruction here,
+          // is an empty sequence.
+          XPath emptySeqXPath = new XPath(XPathParser.XPATH_EXPR_STR_EMPTY_SEQUENCE, srcLocator, 
+                                                                                  null, XPath.SELECT, null);
+          xslSequenceVal = emptySeqXPath.execute(xctxt, DTM.NULL, null);
+      }
+      
+      SerializationHandler handler = transformer.getSerializationHandler();
+      
+      if (xslSequenceVal != null) {
+          int xObjectType = xslSequenceVal.getType();
+          String strVal = null;
+  
+          switch (xObjectType) {           
+              case XObject.CLASS_NODESET :          
+                  ElemCopyOf.copyOfActionOnNodeSet((XNodeSet)xslSequenceVal, transformer, handler, xctxt);          
+                break;
+              case XObject.CLASS_RTREEFRAG :
+                SerializerUtils.outputResultTreeFragment(handler, xslSequenceVal, xctxt);
+                break;
+              case XObject.CLASS_RESULT_SEQUENCE :         
+                ResultSequence resultSequence = (ResultSequence)xslSequenceVal;          
+                ElemCopyOf.copyOfActionOnResultSequence(resultSequence, transformer, handler, xctxt, true);          
+                break;
+              default :
+                // no op
+          }
+          
+          boolean isToAddStrValSerializationSuffix = isToAddStrValSerializationSuffix(xctxt); 
+          
+          if ((xslSequenceVal instanceof XBoolean) || (xslSequenceVal instanceof XNumber) || 
+                                                                    (xslSequenceVal instanceof XString)) {
+              if (isToAddStrValSerializationSuffix) {
+                 strVal = xslSequenceVal.str() + STRING_VAL_SERIALIZATION_SUFFIX;
+              }
+              else {
+                 strVal = xslSequenceVal.str();  
+              }
+              
+              handler.characters(strVal.toCharArray(), 0, strVal.length());
+          }
+          else if (xslSequenceVal instanceof XSAnyAtomicType) {
+              if (isToAddStrValSerializationSuffix) {
+                 strVal = ((XSAnyAtomicType)xslSequenceVal).stringValue() + STRING_VAL_SERIALIZATION_SUFFIX;
+              }
+              else {
+                 strVal = ((XSAnyAtomicType)xslSequenceVal).stringValue();
+              }
+              
+              handler.characters(strVal.toCharArray(), 0, strVal.length());
+          }
+          else if (xslSequenceVal instanceof InlineFunction) {
+              throw new TransformerException("XTDE0450 : Cannot add a function item to an XDM result tree, "
+                                                                                                   + "via xsl:sequence instruction.", srcLocator);
+          }
+       }
+    }
+    catch (SAXException se) {
+       throw new TransformerException(se);
+    }
+    finally {      
+       xctxt.popCurrentNode();
+    }
+    
+    // Restore the original xpath context, on the xslt transformer object
+    transformer.setXPathContext(xctxtOriginal);    
+  }
+
+  /**
+   * This function is called after everything else has been
+   * recomposed, and allows the template to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException {    
+     StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    
+     java.util.Vector vnames = cstate.getVariableNames();
+        
+     fVars = (Vector)vnames.clone();
+     fGlobalsSize = cstate.getGlobalsSize();
+        
+     if (m_selectPattern != null) {
+        m_selectPattern.fixupVariables(vnames, cstate.getGlobalsSize());
+     }
+    
+     super.compose(sroot);
+  }
+  
+  /**
+   * This after the template's children have been composed.
+   */
+  public void endCompose(StylesheetRoot sroot) throws TransformerException
+  {
+     super.endCompose(sroot);
+  }
+  
+  /**
+   * Set the parent as an ElemTemplateElement.
+   *
+   * @param p This node's parent as an ElemTemplateElement
+   */
+  public void setParentElem(ElemTemplateElement p)
+  {
+    super.setParentElem(p);
+  }
+
+  
+  /**
+   * Call the children visitors.
+   * 
+   * @param visitor The visitor whose appropriate method will be called.
+   */
+  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
+  {
+  	if (m_selectPattern != null) {
+  	   m_selectPattern.getExpression().callVisitors(m_selectPattern, visitor);
+  	}
+  	
+    super.callChildVisitors(visitor, callAttrs);
+  }
+  
+  /**
+   * This method determines that, should a XalanJ serialization suffix be added, when
+   * emitting xdm atomic values to an XSLT result sequence.
+   */
+  private boolean isToAddStrValSerializationSuffix(XPathContext xctxt) throws TransformerException {
+     
+     boolean isToAddStrValSerializationSuffix = true;
+     
+     ElemTemplateElement elemTemplateElem = getParentElem();
+     
+     String asAttrStrVal = null;
+     
+     while (elemTemplateElem != null) {
+        if (elemTemplateElem instanceof ElemFunction) {
+           asAttrStrVal = ((ElemFunction)elemTemplateElem).getAs();
+           break;
+        }
+        else if (elemTemplateElem instanceof ElemVariable) {
+           asAttrStrVal = ((ElemVariable)elemTemplateElem).getAs();
+           break;
+        }
+        else {
+           elemTemplateElem = elemTemplateElem.getParentElem();  
+        }
+     }
+     
+     if (asAttrStrVal != null) {
+         XPath seqTypeXPath = new XPath(asAttrStrVal, xctxt.getSAXLocator(), 
+                                                                        xctxt.getNamespaceContext(), 
+                                                                        XPath.SELECT, null, true);
+         XObject seqTypeExpressionEvalResult = seqTypeXPath.execute(xctxt, xctxt.getContextNode(), 
+                                                                             xctxt.getNamespaceContext());
+         SequenceTypeData seqExpectedTypeData = (SequenceTypeData)seqTypeExpressionEvalResult;
+         if (seqExpectedTypeData.getSequenceTypeKindTest() != null) {
+            isToAddStrValSerializationSuffix = false; 
+         }
+     }
+     
+     return isToAddStrValSerializationSuffix; 
+  }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemTemplate.java b/src/org/apache/xalan/templates/ElemTemplate.java
index 31c63ccb..3b996461 100644
--- a/src/org/apache/xalan/templates/ElemTemplate.java
+++ b/src/org/apache/xalan/templates/ElemTemplate.java
@@ -447,7 +447,7 @@ public class ElemTemplate extends ElemTemplateElement
             }
             else {
                ElemCopyOf.copyOfActionOnResultSequence((ResultSequence)templateEvalResultForAsAttr, 
-                                                                                                transformer, handler, xctxt); 
+                                                                                                transformer, handler, xctxt, false); 
             }
         } 
         catch (TransformerException ex) {
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 8ebf0c31..715ea666 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -315,7 +315,7 @@ public class ElemVariable extends ElemTemplateElement
    * @throws TransformerException
    */
   public XObject getValue(TransformerImpl transformer, int sourceNode) 
-                                                                 throws TransformerException
+                                                                    throws TransformerException
   {
 
     XObject var = null;
@@ -533,37 +533,47 @@ public class ElemVariable extends ElemTemplateElement
          var = XString.EMPTYSTRING;
       }
       else {
-        int df;
-
-		try {
-			if(m_parentNode instanceof Stylesheet) // Global variable
-				df = transformer.transformToGlobalRTF(this);
-			else
-				df = transformer.transformToRTF(this);
-    	}
-		finally { 
-		    // no op
+        int rootNodeHandleOfRtf;
+        
+	    if (m_parentNode instanceof Stylesheet) {
+	       // Global variable
+		   rootNodeHandleOfRtf = transformer.transformToGlobalRTF(this);
 	    }
+		else {
+		   rootNodeHandleOfRtf = transformer.transformToRTF(this);
+		}
 		
-		// With XSLT 3.0, RTFs are treated as proper node sets
-		NodeList nodeList = (new XRTreeFrag(df, xctxt, this)).convertToNodeset();		
+		// With XSLT 3.0, RTFs are treated as XDM node sets
+		NodeList nodeList = (new XRTreeFrag(rootNodeHandleOfRtf, xctxt, this)).convertToNodeset();		
 		
-		var = new XNodeSetForDOM(nodeList, xctxt); 
+		var = new XNodeSetForDOM(nodeList, xctxt);
       }
     }
     catch (SAXException se) {
-        throw new TransformerException(se);
+       throw new TransformerException(se);
     }
     finally {      
        xctxt.popCurrentNode();
     }
     
-    // Restore the original xpath context, on the xslt transformer object
-    transformer.setXPathContext(xctxtOriginal);
-    
     if (m_asAttr != null) {
-       var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt);  
+       if (var instanceof XNodeSetForDOM) {
+          XObject variableConvertedVal = ElemFunction.preprocessXslFunctionOrAVariableResult(
+                                                                                           (XNodeSetForDOM)var, m_asAttr, xctxt);
+          if (variableConvertedVal != null) {
+             var = variableConvertedVal;    
+          }
+          else {
+             var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt); 
+          }
+       }       
+       else {
+          var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt); 
+       }
     }
+    
+    // Restore the original xpath context, on the xslt transformer object
+    transformer.setXPathContext(xctxtOriginal);
         
     return var;
     
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index f5eee541..070bcf49 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -109,7 +109,7 @@ public class XPathParser
   // we translate that within this XPath parser implementation, to an XPath
   // range "to" expression using this class field (this equivalently produces
   // an xdm empty sequence).
-  private static final String XPATH_EXPR_STR_EMPTY_SEQUENCE = "1 to 0";
+  public static final String XPATH_EXPR_STR_EMPTY_SEQUENCE = "1 to 0";
   
   private static final List<String> fXpathOpArrTokensList = Arrays.asList(XPATH_OP_ARR);
   
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 0742c207..e636536c 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -95,7 +95,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
                 TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class,
                 XslVariableAttributeAsTests.class, InstanceOfExprTests.class, XslTemplateAttributeAsTests.class,
-                XslFunctionTests.class, FnRoundTests.class })
+                XslFunctionTests.class, FnRoundTests.class, XslSequenceInstTests.class })
 public class AllXsl3Tests {
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XslSequenceInstTests.java b/tests/org/apache/xalan/xslt3/XslSequenceInstTests.java
new file mode 100644
index 00000000..9b255a0f
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/XslSequenceInstTests.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSLT stylesheet test cases, to test xsl:sequence 
+ * instruction.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XslSequenceInstTests extends XslTransformTestsUtil {
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + 
+                                                                                                           "xsl_sequence_inst/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + 
+                                                                                                           "xsl_sequence_inst/gold/";      
+
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xslSequenceTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslSequenceTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslSequenceTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";
+                               
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslSequenceTest4() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);      
+    }
+    
+    @Test
+    public void xslSequenceTest5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/tests/xsl_sequence_inst/gold/test1.out b/tests/xsl_sequence_inst/gold/test1.out
new file mode 100644
index 00000000..5f65a8a3
--- /dev/null
+++ b/tests/xsl_sequence_inst/gold/test1.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><output>37</output>
diff --git a/tests/xsl_sequence_inst/gold/test2.out b/tests/xsl_sequence_inst/gold/test2.out
new file mode 100644
index 00000000..2dd567c4
--- /dev/null
+++ b/tests/xsl_sequence_inst/gold/test2.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><output>4.36</output>
diff --git a/tests/xsl_sequence_inst/gold/test3.out b/tests/xsl_sequence_inst/gold/test3.out
new file mode 100644
index 00000000..6b1ef787
--- /dev/null
+++ b/tests/xsl_sequence_inst/gold/test3.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><output>10</output>
diff --git a/tests/xsl_sequence_inst/gold/test4.out b/tests/xsl_sequence_inst/gold/test4.out
new file mode 100644
index 00000000..9cde98ba
--- /dev/null
+++ b/tests/xsl_sequence_inst/gold/test4.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><output>2010-10-05</output>
diff --git a/tests/xsl_sequence_inst/gold/test5.out b/tests/xsl_sequence_inst/gold/test5.out
new file mode 100644
index 00000000..1041290d
--- /dev/null
+++ b/tests/xsl_sequence_inst/gold/test5.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><output>
+  <productsSummary>
+    <count>5</count>
+    <avgPrice>4.04</avgPrice>
+  </productsSummary>
+</output>
diff --git a/tests/xsl_sequence_inst/test1.xsl b/tests/xsl_sequence_inst/test1.xsl
new file mode 100644
index 00000000..2821af63
--- /dev/null
+++ b/tests/xsl_sequence_inst/test1.xsl
@@ -0,0 +1,45 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test, to test an xsl:sequence 
+       instruction.
+       
+       This stylesheet example, is borrowed from XSLT 3.0
+       spec.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <output>
+        <xsl:variable name="values" as="xs:integer*">
+	       <xsl:sequence select="(1,2,3,4)"/>
+	       <xsl:sequence select="(8,9,10)"/>
+	    </xsl:variable>
+        <xsl:value-of select="sum($values)"/>
+     </output>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/xsl_sequence_inst/test1_a.xml b/tests/xsl_sequence_inst/test1_a.xml
new file mode 100644
index 00000000..518fcd98
--- /dev/null
+++ b/tests/xsl_sequence_inst/test1_a.xml
@@ -0,0 +1,22 @@
+<products>
+  <product price="5">
+    <id>1</id>
+    <desc>a1</desc>
+  </product>
+  <product cost="3.2">
+    <id>2</id>
+    <desc>a2</desc>
+  </product>
+  <product price="2">
+    <id>3</id>
+    <desc>a3</desc>
+  </product>
+  <product price="7">
+    <id>4</id>
+    <desc>a4</desc>
+  </product>
+  <product price="3">
+    <id>5</id>
+    <desc>a5</desc>
+  </product>
+</products>
\ No newline at end of file
diff --git a/tests/xsl_sequence_inst/test2.xsl b/tests/xsl_sequence_inst/test2.xsl
new file mode 100644
index 00000000..9baf9efb
--- /dev/null
+++ b/tests/xsl_sequence_inst/test2.xsl
@@ -0,0 +1,55 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, to test an xsl:sequence 
+       instruction.
+       
+       This stylesheet example, is borrowed from XSLT 3.0
+       spec.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/">
+     <output>        
+         <xsl:variable name="prices" as="xs:decimal*">
+	        <xsl:for-each select="//product">
+	           <xsl:choose>
+	              <xsl:when test="@price">
+	                 <xsl:sequence select="xs:decimal(@price)"/>
+	              </xsl:when>
+	              <xsl:otherwise>
+	                 <xsl:sequence select="xs:decimal(@cost) * 1.5"/>
+	              </xsl:otherwise>
+	           </xsl:choose>
+	        </xsl:for-each>
+	     </xsl:variable>
+         <xsl:value-of select="avg($prices)"/>
+     </output>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/xsl_sequence_inst/test3.xsl b/tests/xsl_sequence_inst/test3.xsl
new file mode 100644
index 00000000..5ae2d88b
--- /dev/null
+++ b/tests/xsl_sequence_inst/test3.xsl
@@ -0,0 +1,46 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:fn0="http://ns0"
+                exclude-result-prefixes="xs fn0"
+                version="3.0">
+  
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test, to test an xsl:sequence 
+       instruction.
+  -->
+                  
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/">
+     <output>
+        <xsl:value-of select="count(fn0:func1())"/>
+     </output>
+  </xsl:template>
+  
+  <xsl:function name="fn0:func1" as="xs:integer*">
+     <xsl:for-each select="1 to 10">
+        <xsl:variable name="val" select="."/>
+        <xsl:sequence select="$val"/>
+     </xsl:for-each>
+  </xsl:function>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/xsl_sequence_inst/test4.xsl b/tests/xsl_sequence_inst/test4.xsl
new file mode 100644
index 00000000..529c6b05
--- /dev/null
+++ b/tests/xsl_sequence_inst/test4.xsl
@@ -0,0 +1,42 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test, to test an xsl:sequence 
+       instruction.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/">
+     <output>
+        <xsl:variable name="dates" as="xs:date*">
+           <xsl:sequence select="(xs:date('2005-10-12'), xs:date('2001-10-02'), 
+                                  xs:date('2010-10-05'), xs:date('2003-10-07'))"/>
+        </xsl:variable>
+        <xsl:value-of select="max($dates)"/>
+     </output>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/xsl_sequence_inst/test5.xsl b/tests/xsl_sequence_inst/test5.xsl
new file mode 100644
index 00000000..e17d3fbe
--- /dev/null
+++ b/tests/xsl_sequence_inst/test5.xsl
@@ -0,0 +1,53 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:fn0="http://fn0"
+                exclude-result-prefixes="xs fn0"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, to test an xsl:sequence 
+       instruction.
+  -->                 
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/products">
+     <output>
+        <xsl:copy-of select="fn0:analyzeProductList(product)"/>
+     </output>
+  </xsl:template>
+  
+  <xsl:function name="fn0:analyzeProductList" as="element()">
+     <xsl:param name="productList" as="element()*"/>
+     <productsSummary>
+        <count>
+           <xsl:sequence select="count($productList)"/>
+        </count>
+        <avgPrice>
+           <xsl:sequence select="avg(for $product in $productList return ($product/@price | $product/@cost))"/>
+        </avgPrice>
+     </productsSummary>
+  </xsl:function>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org