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/06 06:34:34 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 'instance of' expression, along with few new related working test cases. also committing little bit of codebase refactoring, on this xalanj dev repos branch.

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 b2bf2999 committing implementation of xpath 3.1 'instance of' expression, along with few new related working test cases. also committing little bit of codebase refactoring, on this xalanj dev repos branch.
     new a67a8f1a Merge pull request #76 from mukulga/xalan-j_xslt3.0_mukul
b2bf2999 is described below

commit b2bf2999a5266b9e0cbd2212d20841fb7ec4d920
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Wed Sep 6 12:00:21 2023 +0530

    committing implementation of xpath 3.1 'instance of' expression, along with few new related working test cases. also committing little bit of codebase refactoring, on this xalanj dev repos branch.
---
 src/org/apache/xalan/templates/ElemVariable.java   |  19 +-
 src/org/apache/xpath/compiler/Compiler.java        |  17 +
 src/org/apache/xpath/compiler/OpCodes.java         |   9 +-
 src/org/apache/xpath/compiler/XPathParser.java     |  16 +
 .../xpath/composite/SequenceTypeSupport.java       | 686 ++++++++++++---------
 src/org/apache/xpath/operations/InstanceOf.java    |  57 ++
 tests/instanceof_expr/gold/test1.out               |  14 +
 tests/instanceof_expr/gold/test2.out               |  29 +
 tests/instanceof_expr/test1.xsl                    |  77 +++
 tests/instanceof_expr/test1_a.xml                  |   7 +
 tests/instanceof_expr/test1_b.xml                  |   4 +
 tests/instanceof_expr/test2.xsl                    |  60 ++
 .../apache/xalan/xpath3/InstanceOfExprTests.java   |  70 +++
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   3 +-
 14 files changed, 773 insertions(+), 295 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 992dedbe..c624ddfa 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -347,7 +347,7 @@ public class ElemVariable extends ElemTemplateElement
                                                                                         selectExpression);
             if (evalResult != null) {
                 if (m_asAttr != null) {
-                   evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+                   evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, null, xctxt);  
                 }
                 
                 return evalResult;    
@@ -361,7 +361,7 @@ public class ElemVariable extends ElemTemplateElement
             if ((evalResult instanceof ResultSequence) || 
                                                 (evalResult instanceof XSAnyType)) {
                 if (m_asAttr != null) {
-                   evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+                   evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, null, xctxt);  
                 }
                 
                 return evalResult; 
@@ -371,7 +371,7 @@ public class ElemVariable extends ElemTemplateElement
             XObject evalResult = selectExpression.execute(xctxt);
             
             if (m_asAttr != null) {
-               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, null, xctxt);  
             }
              
             return evalResult;
@@ -380,7 +380,7 @@ public class ElemVariable extends ElemTemplateElement
             XObject evalResult = ((Range)selectExpression).execute(xctxt);
             
             if (m_asAttr != null) {
-               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, null, xctxt);  
             }
              
             return evalResult; 
@@ -394,7 +394,7 @@ public class ElemVariable extends ElemTemplateElement
             XObject evalResult = opn.operate(leftOperand, rightOperand);
             
             if (m_asAttr != null) {
-               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, xctxt);  
+               evalResult = SequenceTypeSupport.convertXDMValueToAnotherType(evalResult, m_asAttr, null, xctxt);  
             }
              
             return evalResult;
@@ -403,7 +403,8 @@ public class ElemVariable extends ElemTemplateElement
             XObject xpath3ContextItem = xctxt.getXPath3ContextItem();
             if (xpath3ContextItem != null) {               
               if (m_asAttr != null) {
-                 xpath3ContextItem = SequenceTypeSupport.convertXDMValueToAnotherType(xpath3ContextItem, m_asAttr, xctxt);  
+                 xpath3ContextItem = SequenceTypeSupport.convertXDMValueToAnotherType(xpath3ContextItem, m_asAttr, 
+                                                                                                               null, xctxt);  
               }
                 
               return xpath3ContextItem;
@@ -426,7 +427,7 @@ public class ElemVariable extends ElemTemplateElement
                var = new XNodeSet(dtmIter);
                
                if (m_asAttr != null) {
-                  var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, xctxt);  
+                  var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt);  
                }
                  
                return var; 
@@ -519,7 +520,7 @@ public class ElemVariable extends ElemTemplateElement
                var = resultSeq;
                
                if (m_asAttr != null) {
-                  var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, xctxt);  
+                  var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt);  
                }
                   
                return var;
@@ -577,7 +578,7 @@ public class ElemVariable extends ElemTemplateElement
     transformer.setXPathContext(xctxtOriginal);
     
     if (m_asAttr != null) {
-       var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, xctxt);  
+       var = SequenceTypeSupport.convertXDMValueToAnotherType(var, m_asAttr, null, xctxt);  
     }
         
     return var;
diff --git a/src/org/apache/xpath/compiler/Compiler.java b/src/org/apache/xpath/compiler/Compiler.java
index dd5a99fb..7f759f20 100644
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ b/src/org/apache/xpath/compiler/Compiler.java
@@ -45,6 +45,7 @@ import org.apache.xpath.operations.Div;
 import org.apache.xpath.operations.Equals;
 import org.apache.xpath.operations.Gt;
 import org.apache.xpath.operations.Gte;
+import org.apache.xpath.operations.InstanceOf;
 import org.apache.xpath.operations.Lt;
 import org.apache.xpath.operations.Lte;
 import org.apache.xpath.operations.Minus;
@@ -174,6 +175,8 @@ public class Compiler extends OpMap
       expr = simpleMapOperator(opPos); break;
     case OpCodes.OP_SEQUENCE_TYPE_EXPR :
       expr = sequenceTypeExpr(opPos); break;
+    case OpCodes.OP_INSTANCE_OF :
+      expr = instanceOfExpr(opPos); break;
     case OpCodes.OP_LTE :
       expr = lte(opPos); break;
     case OpCodes.OP_LT :
@@ -532,6 +535,20 @@ public class Compiler extends OpMap
   {
       return XPathParser.fXpathSequenceTypeExpr;
   }
+  
+  /**
+   * Compile an XPath 3.1 "instance of" expression.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   * 
+   * @return reference to {@link org.apache.xpath.operations.InstanceOf} instance.
+   * 
+   * @throws TransformerException if a error occurs creating the Expression.
+   */
+  protected Expression instanceOfExpr(int opPos) throws TransformerException
+  {
+    return compileOperation(new InstanceOf(), opPos);
+  }
 
   /**
    * Compile a '>=' operation.
diff --git a/src/org/apache/xpath/compiler/OpCodes.java b/src/org/apache/xpath/compiler/OpCodes.java
index 3d10a259..e73c0bd2 100644
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ b/src/org/apache/xpath/compiler/OpCodes.java
@@ -726,8 +726,15 @@ public class OpCodes
   public static final int OP_SIMPLE_MAP_OPERATOR = 72;
   
   public static final int OP_SEQUENCE_TYPE_EXPR = 73;
+  
+  /**
+   * For XPath 3.1 "instance of" expression.
+   * 
+   * @xsl.usage advanced
+   */
+  public static final int OP_INSTANCE_OF = 74;
 
   /** The next free ID. Please keep this up to date. */
-  private static final int NEXT_FREE_ID = 74;
+  private static final int NEXT_FREE_ID = 75;
   
 }
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 6a6255fb..1d627afe 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -1821,6 +1821,7 @@ public class XPathParser
    * | RelationalExpr 'is' AdditiveExpr
    * | RelationalExpr '<<' AdditiveExpr
    * | RelationalExpr '>>' AdditiveExpr
+   * | RelationalExpr 'instance of' SequenceType
    *
    * @param addPos Position where expression is to be added, or -1 for append.
    *
@@ -2001,6 +2002,21 @@ public class XPathParser
              m_ops.getOp(addPos + op1 + 1) + op1);
           addPos += 2;
       }
+      else if (tokenIs("instance") && lookahead("of", 1)) {
+          // support for XPath 3.1 "instance of" expression
+          
+          consumeExpected("instance");
+          consumeExpected("of");
+          
+          insertOp(addPos, 2, OpCodes.OP_INSTANCE_OF);
+          
+          int op1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+          
+          fXpathSequenceTypeExpr = SequenceTypeExpr();
+          m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, 
+                                                  m_ops.getOp(addPos + op1 + 1) + op1);
+          addPos += 2;
+      }
     }
 
     return addPos;
diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
index 2d38cfb8..ed7b8bc9 100644
--- a/src/org/apache/xpath/composite/SequenceTypeSupport.java
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -57,7 +57,7 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 /**
- * This class provides few utility methods, to help implement
+ * This class provides few utility methods, to help evaluate
  * XPath 3.1 sequence type expressions.
  * 
  * Ref : https://www.w3.org/TR/xpath-31/#id-sequencetype-syntax
@@ -105,6 +105,8 @@ public class SequenceTypeSupport {
     
     public static int XS_FLOAT = 15;
     
+    // following are constant int values denoting XPath sequence type 
+    // KindTest expressions.
     
     public static int ELEMENT_KIND = 101;
     
@@ -149,10 +151,9 @@ public class SequenceTypeSupport {
      *  
      * @param srcValue                     an XObject object instance that represents a
      *                                     source xdm value. 
-     * @param sequenceTypeXPathExprStr     a string representing an XPath 3.1 sequence type,
-     *                                     conforming to which the source value srcValue needs
-     *                                     to be converted. 
-     * @param xctxt                        the current XPath context object.
+     * @param sequenceTypeXPathExprStr     an XPath sequence type expression string 
+     * @param seqExpectedTypeDataInp       an XPath sequence type compiled expression                                                                  
+     * @param xctxt                        the current XPath context object
      * 
      * @return                             an XObject object instance produced, as a result of data type 
      *                                     conversion performed by this method on an object instance
@@ -161,21 +162,34 @@ public class SequenceTypeSupport {
      * @throws TransformerException 
      */
     public static XObject convertXDMValueToAnotherType(XObject srcValue, String sequenceTypeXPathExprStr, 
+                                                                                       SequenceTypeData seqExpectedTypeDataInp, 
                                                                                        XPathContext xctxt) throws TransformerException {
         XObject result = null;
         
-        final int contextNode = xctxt.getContextNode(); 
+        int contextNode = DTM.NULL;        
+        SourceLocator srcLocator = null;
         
-        SourceLocator srcLocator = xctxt.getSAXLocator();
+        if (xctxt != null) {
+           contextNode = xctxt.getContextNode();        
+           srcLocator = xctxt.getSAXLocator();
+        }
         
         try {
-            XPath seqTypeXPath = new XPath(sequenceTypeXPathExprStr, srcLocator, 
-                                                                            xctxt.getNamespaceContext(), XPath.SELECT, null, true);
+            XPath seqTypeXPath = null;
+            XObject seqTypeExpressionEvalResult = null;
+            SequenceTypeData seqExpectedTypeData = null;
+            
+            if (xctxt != null) {
+               seqTypeXPath = new XPath(sequenceTypeXPathExprStr, srcLocator, 
+                                                                          xctxt.getNamespaceContext(), XPath.SELECT, null, true);
             
-            XObject seqTypeExpressionEvalResult = seqTypeXPath.execute(xctxt, contextNode, 
-                                                                                    xctxt.getNamespaceContext());
+               seqTypeExpressionEvalResult = seqTypeXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
             
-            SequenceTypeData seqExpectedTypeData = (SequenceTypeData)seqTypeExpressionEvalResult;
+               seqExpectedTypeData = (SequenceTypeData)seqTypeExpressionEvalResult;
+            }
+            else {
+               seqExpectedTypeData = seqExpectedTypeDataInp; 
+            }
             
             int expectedType = seqExpectedTypeData.getSequenceType();            
             int itemTypeOccurenceIndicator = seqExpectedTypeData.getItemTypeOccurrenceIndicator();
@@ -197,7 +211,7 @@ public class SequenceTypeSupport {
                    }
                 }
                 else {
-                   result = convertStringValueToAnExpectedType(srcStrVal, expectedType);
+                   result = castStringValueToAnExpectedType(srcStrVal, expectedType);
                 }
             }
             else if (srcValue instanceof XSString) {           
@@ -216,7 +230,7 @@ public class SequenceTypeSupport {
                   }
                }
                else {
-                  result = convertStringValueToAnExpectedType(srcStrVal, expectedType);
+                  result = castStringValueToAnExpectedType(srcStrVal, expectedType);
                }
             }
             else if (srcValue instanceof XNumber) {
@@ -338,282 +352,28 @@ public class SequenceTypeSupport {
             }
             else if (srcValue instanceof XSUntyped) {
                String srcStrVal = ((XSUntyped)srcValue).stringValue();
-               result = convertXDMValueToAnotherType(new XSString(srcStrVal), sequenceTypeXPathExprStr, xctxt);
+               result = convertXDMValueToAnotherType(new XSString(srcStrVal), sequenceTypeXPathExprStr, 
+                                                                                                    seqExpectedTypeDataInp, xctxt);
             }
             else if (srcValue instanceof XSUntypedAtomic) {
                String srcStrVal = ((XSUntypedAtomic)srcValue).stringValue();
-               result = convertXDMValueToAnotherType(new XSString(srcStrVal), sequenceTypeXPathExprStr, xctxt);
+               result = convertXDMValueToAnotherType(new XSString(srcStrVal), sequenceTypeXPathExprStr, 
+                                                                                                    seqExpectedTypeDataInp, xctxt);
             }
             else if (srcValue instanceof XNodeSetForDOM) {               
-               XNodeSetForDOM xNodeSetForDOM = (XNodeSetForDOM)srcValue;
-               DTMNodeList dtmNodeList = (DTMNodeList)(xNodeSetForDOM.object());
-               
-               DTMManager dtmMgr = xNodeSetForDOM.getDTMManager();
-               
-               List<Integer> nodesDtmList = new ArrayList<Integer>();
-               
-               ResultSequence convertedResultSeq = new ResultSequence();
-               
-               Node localRootNode = dtmNodeList.item(0);
-               NodeList nodeList = localRootNode.getChildNodes();
-               int nodeSetLen = nodeList.getLength();
-               
-               if ((nodeSetLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
-                                                                                                     OccurenceIndicator.ZERO_OR_ONE))) {
-                  throw new TransformerException("XTTE0570 : A sequence of size " + nodeSetLen + ", cannot be cast to a type " 
-                                                                                                                 + sequenceTypeXPathExprStr + ".", srcLocator);  
-               }
-               else {                   
-                  for (int idx = 0; idx < nodeSetLen; idx++) {
-                     Node node = nodeList.item(idx);
-                     
-                     int nodeDtmHandle = dtmMgr.getDTMHandleFromNode(node);
-                     nodesDtmList.add(Integer.valueOf(nodeDtmHandle));
-                     
-                     String sequenceTypeNewXPathExprStr = null;                    
-                     if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
-                                                                                                     sequenceTypeXPathExprStr.endsWith(PLUS)) {
-                         sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
-                     }
-                     
-                     if (sequenceTypeKindTest != null) {
-                        String nodeName = node.getLocalName();
-                        String nodeNsUri = node.getNamespaceURI();
-                        
-                        if (sequenceTypeKindTest.getDataTypeName() != null) {
-                            String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr; 
-                            throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
-                                                                                                            ". The supplied value " + nodeName + " does not match. The "
-                                                                                                            + "supplied node has not been validated with a schema.", srcLocator); 
-                        }
-                        else {
-                            if (node.getNodeType() == Node.ELEMENT_NODE) {
-                               String elemNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
-                               if (elemNodeKindTestNodeName == null || "".equals(elemNodeKindTestNodeName) || 
-                                                                                                       STAR.equals(elemNodeKindTestNodeName)) {
-                                   elemNodeKindTestNodeName = nodeName;  
-                               }
-                               
-                               boolean isSeqTypeMatchOk = false;
-                               
-                               if ((sequenceTypeKindTest.getKindVal() == ELEMENT_KIND) && (nodeName.equals(elemNodeKindTestNodeName)) 
-                                                                                                && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
-                                  isSeqTypeMatchOk = true;
-                               }
-                               else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
-                                  isSeqTypeMatchOk = true;
-                               }
-                               
-                               if (!isSeqTypeMatchOk) {
-                                   String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                   throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
-                                                                                                         ". The supplied value " + nodeName + " does not match.", srcLocator); 
-                               }
-                            }
-                            else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
-                                String attrNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
-                                if (attrNodeKindTestNodeName == null || "".equals(attrNodeKindTestNodeName) || 
-                                                                                                        STAR.equals(attrNodeKindTestNodeName)) {
-                                   attrNodeKindTestNodeName = nodeName;  
-                                }
-                                
-                                boolean isSeqTypeMatchOk = false;
-                                
-                                if ((sequenceTypeKindTest.getKindVal() == ATTRIBUTE_KIND) && (nodeName.equals(attrNodeKindTestNodeName)) 
-                                                                                                           && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
-                                   isSeqTypeMatchOk = true;  
-                                }
-                                else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
-                                   isSeqTypeMatchOk = true;  
-                                }
-                                
-                                if (!isSeqTypeMatchOk) {
-                                    String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                    throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
-                                                                                                          ". The supplied value " + nodeName + " does not match.", srcLocator);  
-                                } 
-                            }
-                            else if (node.getNodeType() == Node.TEXT_NODE) {
-                                if (!((sequenceTypeKindTest.getKindVal() == TEXT_KIND) || 
-                                      (sequenceTypeKindTest.getKindVal() == NODE_KIND) || 
-                                      (sequenceTypeKindTest.getKindVal() == ITEM_KIND))) {
-                                   String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                   throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + ". "
-                                                                                                                     + "The supplied value does not match.", srcLocator);  
-                                }
-                            }
-                        }
-                     }
-                     else {
-                        if (sequenceTypeNewXPathExprStr == null) {
-                           sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr;  
-                        }
-                          
-                        String nodeStrVal = node.getNodeValue();
-                        XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, xctxt);                       
-                        convertedResultSeq.add(xObject); 
-                     }
-                  }
-               }
-               
-               if (convertedResultSeq.size() > 0) {
-                  result = convertedResultSeq;  
-               }
-               else {
-                  result = new XNodeSet(nodesDtmList, dtmMgr); 
-               }
+               result = castXNodeSetForDOMInstance(srcValue, sequenceTypeXPathExprStr, seqExpectedTypeDataInp, 
+                                                                              xctxt, srcLocator, itemTypeOccurenceIndicator, 
+                                                                                                                       sequenceTypeKindTest);
             }
             else if (srcValue instanceof XNodeSet) {
-                XNodeSet xdmNodeSet = (XNodeSet)srcValue;
-                
-                int nodeSetLen = xdmNodeSet.getLength();
-                
-                if ((nodeSetLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
-                                                                                                     OccurenceIndicator.ZERO_OR_ONE))) {
-                    throw new TransformerException("XTTE0570 : A sequence of size " + nodeSetLen + ", cannot be cast to a type " 
-                                                                                                         + sequenceTypeXPathExprStr + ".", srcLocator);  
-                }
-                else { 
-                    ResultSequence convertedResultSeq = new ResultSequence();
-                    
-                    DTMManager dtmMgr = (DTMManager)xctxt;
-                    
-                    DTMIterator dtmIter = xdmNodeSet.iterRaw();
-                    
-                    int nextNodeDtmHandle;
-                           
-                    while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {               
-                       XNodeSet nodeSetItem = new XNodeSet(nextNodeDtmHandle, xctxt);                                           
-                       
-                       String sequenceTypeNewXPathExprStr = null;                    
-                       if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
-                                                                                           sequenceTypeXPathExprStr.endsWith(PLUS)) {
-                          sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
-                       }
-                       
-                       if (sequenceTypeKindTest != null) {
-                          DTM dtm = dtmMgr.getDTM(nextNodeDtmHandle);
-                          
-                          String nodeName = dtm.getNodeName(nextNodeDtmHandle);
-                          String nodeNsUri = dtm.getNamespaceURI(nextNodeDtmHandle);
-                          
-                          if (sequenceTypeKindTest.getDataTypeName() != null) {
-                             String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr; 
-                             throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
-                                                                                                             ". The supplied value " + nodeName + " does not match. The "
-                                                                                                             + "supplied node has not been validated with a schema.", srcLocator); 
-                          }
-                          else {
-                             if (dtm.getNodeType(nextNodeDtmHandle) == DTM.ELEMENT_NODE) {
-                                String elemNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
-                                if (elemNodeKindTestNodeName == null || "".equals(elemNodeKindTestNodeName) || 
-                                                                                                        STAR.equals(elemNodeKindTestNodeName)) {
-                                   elemNodeKindTestNodeName = nodeName;  
-                                }
-                                
-                                if ((sequenceTypeKindTest.getKindVal() == ELEMENT_KIND) && (nodeName.equals(elemNodeKindTestNodeName)) 
-                                                                                                         && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
-                                   convertedResultSeq.add(nodeSetItem);  
-                                }
-                                else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
-                                   convertedResultSeq.add(nodeSetItem); 
-                                }
-                                else {
-                                   String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                   throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
-                                                                                                         ". The supplied value " + nodeName + " does not match.", srcLocator); 
-                                }
-                             }
-                             else if (dtm.getNodeType(nextNodeDtmHandle) == DTM.ATTRIBUTE_NODE) {
-                                String attrNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
-                                if (attrNodeKindTestNodeName == null || "".equals(attrNodeKindTestNodeName) || 
-                                                                                                        STAR.equals(attrNodeKindTestNodeName)) {
-                                   attrNodeKindTestNodeName = nodeName;  
-                                }
-                                
-                                if ((sequenceTypeKindTest.getKindVal() == ATTRIBUTE_KIND) && (nodeName.equals(attrNodeKindTestNodeName)) 
-                                                                                                           && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
-                                    convertedResultSeq.add(nodeSetItem);  
-                                }
-                                else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
-                                    convertedResultSeq.add(nodeSetItem); 
-                                }
-                                else {
-                                    String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                    throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
-                                                                                                          ". The supplied value " + nodeName + " does not match.", srcLocator);  
-                                }
-                             }
-                             else if (dtm.getNodeType(nextNodeDtmHandle) == DTM.TEXT_NODE) {
-                                if (sequenceTypeKindTest.getKindVal() == TEXT_KIND) {
-                                   convertedResultSeq.add(nodeSetItem); 
-                                }
-                                else {
-                                   String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                   throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + ". "
-                                                                                                                    + "The supplied value does not match.", srcLocator); 
-                                }
-                             }
-                             else if (dtm.getNodeType(nextNodeDtmHandle) == DTM.NAMESPACE_NODE) {
-                                 if (sequenceTypeKindTest.getKindVal() == NAMESPACE_NODE_KIND) {
-                                    convertedResultSeq.add(nodeSetItem); 
-                                 }
-                                 else {
-                                    String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
-                                    throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + ". "
-                                                                                                                     + "The supplied value does not match.", srcLocator); 
-                                 }
-                             }
-                             else {
-                                convertedResultSeq.add(nodeSetItem); 
-                             }
-                          }
-                       }
-                       else {
-                          if (sequenceTypeNewXPathExprStr == null) {
-                             sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr;  
-                          }
-                          
-                          String nodeStrVal = nodeSetItem.str();
-                          XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, xctxt);                       
-                          convertedResultSeq.add(xObject);
-                       }
-                    }
-                    
-                    result = convertedResultSeq;
-                }
+               result = castXNodeSetInstance(srcValue, sequenceTypeXPathExprStr, seqExpectedTypeDataInp, 
+                                                                              xctxt, srcLocator, itemTypeOccurenceIndicator, 
+                                                                                                                       sequenceTypeKindTest);
             }
             else if (srcValue instanceof ResultSequence) {
-                ResultSequence srcResultSeq = (ResultSequence)srcValue;
-                
-                int seqLen = srcResultSeq.size();
-                
-                if ((seqLen > 0) && (expectedType == EMPTY_SEQUENCE)) {
-                   throw new TransformerException("XTTE0570 : The sequence doesn't conform to an expected type empty-sequence(). "
-                                                                                               + "The supplied sequence has size " + seqLen + ".", srcLocator);  
-                }
-                else if ((seqLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
-                                                                                                 OccurenceIndicator.ZERO_OR_ONE))) {
-                    throw new TransformerException("XTTE0570 : A sequence of size " + seqLen + ", cannot be cast to a type " 
-                                                                                                                + sequenceTypeXPathExprStr + ".", srcLocator); 
-                }
-                else {
-                    String sequenceTypeNewXPathExprStr = null;                    
-                    if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
-                                                                                        sequenceTypeXPathExprStr.endsWith(PLUS)) {
-                       sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
-                    }
-                    
-                    ResultSequence convertedResultSeq = new ResultSequence();
-                    
-                    for (int idx = 0; idx < srcResultSeq.size(); idx++) {
-                       XObject seqItem = (XObject)(srcResultSeq.item(idx));                       
-                       XObject convertedSeqItem = convertXDMValueToAnotherType(seqItem, sequenceTypeNewXPathExprStr, xctxt);
-                       convertedResultSeq.add(convertedSeqItem);
-                    }
-                    
-                    result = convertedResultSeq; 
-                }
+               result = castResultSequenceInstance(srcValue, sequenceTypeXPathExprStr,
+                        seqExpectedTypeDataInp, xctxt, srcLocator,
+                        expectedType, itemTypeOccurenceIndicator);
             }
         }
         catch (TransformerException ex) {
@@ -634,11 +394,34 @@ public class SequenceTypeSupport {
     }
     
     /**
-     * Convert a string value to an expected xdm type.
+     * Check whether an XObject object instance conforms to an XPath sequence 
+     * type expression.
+     */
+    public static boolean isInstanceOf(XObject srcValue, SequenceTypeData sequenceTypeData) {
+       boolean isInstanceOf = true;
+       
+       XObject resultObj = null;
+       
+       try {
+          resultObj = convertXDMValueToAnotherType(srcValue, null, sequenceTypeData, null);
+       } 
+       catch (TransformerException ex) {        
+          isInstanceOf = false;
+       }
+       
+       if (resultObj == null) {
+          isInstanceOf = false; 
+       }
+       
+       return isInstanceOf; 
+    }
+    
+    /**
+     * Cast a string value to an expected xdm type.
      * 
      * @throws TransformerException
      */
-    private static XObject convertStringValueToAnExpectedType(String srcStrVal, int expectedType) throws TransformerException {
+    private static XObject castStringValueToAnExpectedType(String srcStrVal, int expectedType) throws TransformerException {
         
         XObject result = null;
         
@@ -862,6 +645,341 @@ public class SequenceTypeSupport {
         }
         
         return xmlNamespacesEqual; 
-     }
+    }
+    
+    /**
+     * When for e.g, we've a xsl:variable declaration like following,
+     * 
+     * <xsl:variable name="varName" as="sequenceTypeExpr">
+     *   <!-- sequence constructor -->
+     * </xsl:variable>
+     * 
+     * this method is used, to cast the provided XNodeSetForDOM object instance
+     * (representing xsl:variable's evaluated sequence constructor, when this
+     * sequence constructor represents an XML complex content) to an XObject value
+     * conforming to xsl:variable's sequence type expression which is the value of
+     * xsl:variable's "as" attribute.    
+     */
+    private static XObject castXNodeSetForDOMInstance(XObject srcValue,
+                                                                  String sequenceTypeXPathExprStr,
+                                                                  SequenceTypeData seqExpectedTypeDataInp, XPathContext xctxt,
+                                                                  SourceLocator srcLocator, int itemTypeOccurenceIndicator,
+                                                                  SequenceTypeKindTest sequenceTypeKindTest)
+                                                                                                          throws TransformerException {
+        XObject result = null;
+
+        XNodeSetForDOM xNodeSetForDOM = (XNodeSetForDOM)srcValue;
+        DTMNodeList dtmNodeList = (DTMNodeList)(xNodeSetForDOM.object());
+
+        DTMManager dtmMgr = xNodeSetForDOM.getDTMManager();
+
+        List<Integer> xdmNodesDtmList = new ArrayList<Integer>();
+
+        Node localRootNode = dtmNodeList.item(0);
+        NodeList nodeList = localRootNode.getChildNodes();
+        int nodeSetLen = nodeList.getLength();
+
+        ResultSequence convertedResultSeq = new ResultSequence();
+        
+        if ((nodeSetLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
+                                                                                             OccurenceIndicator.ZERO_OR_ONE))) {
+            throw new TransformerException("XTTE0570 : A sequence of size " + nodeSetLen + ", cannot be cast to a type " 
+                                                                                                         + sequenceTypeXPathExprStr + ".", srcLocator);  
+        }
+        else {            
+            for (int idx = 0; idx < nodeSetLen; idx++) {
+                Node node = nodeList.item(idx);
+
+                int nodeDtmHandle = dtmMgr.getDTMHandleFromNode(node);
+                xdmNodesDtmList.add(Integer.valueOf(nodeDtmHandle));
+
+                String sequenceTypeNewXPathExprStr = null;                    
+                if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
+                                                                                               sequenceTypeXPathExprStr.endsWith(PLUS)) {
+                    sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
+                }
+
+                if (sequenceTypeKindTest != null) {
+                    String nodeName = node.getLocalName();
+                    String nodeNsUri = node.getNamespaceURI();
+
+                    if (sequenceTypeKindTest.getDataTypeName() != null) {
+                        String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr; 
+                        throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
+                                                                                                        ". The supplied value " + nodeName + " does not match. The "
+                                                                                                        + "supplied node has not been validated with a schema.", srcLocator); 
+                    }
+                    else {
+                        if (node.getNodeType() == Node.ELEMENT_NODE) {
+                            String elemNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
+                            if (elemNodeKindTestNodeName == null || "".equals(elemNodeKindTestNodeName) || 
+                                                                                                   STAR.equals(elemNodeKindTestNodeName)) {
+                                elemNodeKindTestNodeName = nodeName;  
+                            }
+
+                            boolean isSeqTypeMatchOk = false;
+
+                            if ((sequenceTypeKindTest.getKindVal() == ELEMENT_KIND) && (nodeName.equals(elemNodeKindTestNodeName)) 
+                                                                                             && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
+                                isSeqTypeMatchOk = true;
+                            }
+                            else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
+                                isSeqTypeMatchOk = true;
+                            }
+
+                            if (!isSeqTypeMatchOk) {
+                                String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                                throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
+                                                                                                                ". The supplied value " + nodeName + " does not match.", srcLocator); 
+                            }
+                        }
+                        else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+                            String attrNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
+                            if (attrNodeKindTestNodeName == null || "".equals(attrNodeKindTestNodeName) || 
+                                                                                                   STAR.equals(attrNodeKindTestNodeName)) {
+                                attrNodeKindTestNodeName = nodeName;  
+                            }
+
+                            boolean isSeqTypeMatchOk = false;
+
+                            if ((sequenceTypeKindTest.getKindVal() == ATTRIBUTE_KIND) && (nodeName.equals(attrNodeKindTestNodeName)) 
+                                                                                               && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
+                                isSeqTypeMatchOk = true;  
+                            }
+                            else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
+                                isSeqTypeMatchOk = true;  
+                            }
+
+                            if (!isSeqTypeMatchOk) {
+                                String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                                throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
+                                                                                                      ". The supplied value " + nodeName + " does not match.", srcLocator);  
+                            } 
+                        }
+                        else if (node.getNodeType() == Node.TEXT_NODE) {
+                            if (!((sequenceTypeKindTest.getKindVal() == TEXT_KIND) || 
+                                                                (sequenceTypeKindTest.getKindVal() == NODE_KIND) || 
+                                                                (sequenceTypeKindTest.getKindVal() == ITEM_KIND))) {
+                                String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                                throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + ". "
+                                                                                                      + "The supplied value does not match.", srcLocator);  
+                            }
+                        }
+                    }
+                }
+                else {
+                    if (sequenceTypeNewXPathExprStr == null) {
+                        sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr;  
+                    }
+
+                    String nodeStrVal = node.getNodeValue();
+                    XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, 
+                                                                                                                      seqExpectedTypeDataInp, xctxt);                       
+                    convertedResultSeq.add(xObject); 
+                }
+            }
+        }
+
+        if (convertedResultSeq.size() > 0) {
+            result = convertedResultSeq;  
+        }
+        else {
+            result = new XNodeSet(xdmNodesDtmList, dtmMgr); 
+        }
+        
+        return result;
+    }
+    
+    /**
+     * This method casts a provided XObject object instance representing an xdm
+     * node set, to another type specified by an xdm sequence type expression.
+     */
+    private static XObject castXNodeSetInstance(XObject srcValue,
+                                                              String sequenceTypeXPathExprStr,
+                                                              SequenceTypeData seqExpectedTypeDataInp, XPathContext xctxt,
+                                                              SourceLocator srcLocator,
+                                                              int itemTypeOccurenceIndicator,
+                                                              SequenceTypeKindTest sequenceTypeKindTest)
+                                                                                                     throws TransformerException {
+        XObject result = null;
+        
+        XNodeSet xdmNodeSet = (XNodeSet)srcValue;
+        
+        int nodeSetLen = xdmNodeSet.getLength();
+        
+        if ((nodeSetLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
+                                                                                             OccurenceIndicator.ZERO_OR_ONE))) {
+            throw new TransformerException("XTTE0570 : A sequence of size " + nodeSetLen + ", cannot be cast to a type " 
+                                                                                                           + sequenceTypeXPathExprStr + ".", srcLocator);  
+        }
+        else { 
+            ResultSequence convertedResultSeq = new ResultSequence();
+            
+            DTMIterator dtmIter = xdmNodeSet.iterRaw();
+            
+            int nextNodeDtmHandle;
+                   
+            while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {               
+               XNodeSet nodeSetItem = new XNodeSet(nextNodeDtmHandle, xctxt);
+               
+               String sequenceTypeNewXPathExprStr = null;
+               if (sequenceTypeXPathExprStr != null) {
+                   if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
+                                                                                                sequenceTypeXPathExprStr.endsWith(PLUS)) {
+                      sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
+                   }
+               }
+               
+               if (sequenceTypeKindTest != null) {
+                  DTM dtm = dtmIter.getDTM(nextNodeDtmHandle);
+                  
+                  String nodeName = dtm.getNodeName(nextNodeDtmHandle);
+                  String nodeNsUri = dtm.getNamespaceURI(nextNodeDtmHandle);
+                  
+                  if (sequenceTypeKindTest.getDataTypeName() != null) {
+                     String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr; 
+                     throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
+                                                                                                     ". The supplied value " + nodeName + " does not match. The "
+                                                                                                     + "supplied node has not been validated with a schema.", srcLocator); 
+                  }
+                  else {
+                     if (dtm.getNodeType(nextNodeDtmHandle) == DTM.ELEMENT_NODE) {
+                        String elemNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
+                        if (elemNodeKindTestNodeName == null || "".equals(elemNodeKindTestNodeName) || 
+                                                                                                STAR.equals(elemNodeKindTestNodeName)) {
+                           elemNodeKindTestNodeName = nodeName;  
+                        }
+                        
+                        if ((sequenceTypeKindTest.getKindVal() == ELEMENT_KIND) && (nodeName.equals(elemNodeKindTestNodeName)) 
+                                                                                                 && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
+                           convertedResultSeq.add(nodeSetItem);  
+                        }
+                        else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
+                           convertedResultSeq.add(nodeSetItem); 
+                        }
+                        else {
+                           String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                           throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
+                                                                                                 ". The supplied value " + nodeName + " does not match.", srcLocator); 
+                        }
+                     }
+                     else if (dtm.getNodeType(nextNodeDtmHandle) == DTM.ATTRIBUTE_NODE) {
+                        String attrNodeKindTestNodeName = sequenceTypeKindTest.getNodeLocalName();
+                        if (attrNodeKindTestNodeName == null || "".equals(attrNodeKindTestNodeName) || 
+                                                                                                STAR.equals(attrNodeKindTestNodeName)) {
+                           attrNodeKindTestNodeName = nodeName;  
+                        }
+                        
+                        if ((sequenceTypeKindTest.getKindVal() == ATTRIBUTE_KIND) && (nodeName.equals(attrNodeKindTestNodeName)) 
+                                                                                                   && (isTwoXmlNamespacesEqual(nodeNsUri, sequenceTypeKindTest.getNodeNsUri()))) {
+                            convertedResultSeq.add(nodeSetItem);  
+                        }
+                        else if ((sequenceTypeKindTest.getKindVal() == NODE_KIND) || (sequenceTypeKindTest.getKindVal() == ITEM_KIND)) {
+                            convertedResultSeq.add(nodeSetItem); 
+                        }
+                        else {
+                            String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                            throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + 
+                                                                                                  ". The supplied value " + nodeName + " does not match.", srcLocator);  
+                        }
+                     }
+                     else if (dtm.getNodeType(nextNodeDtmHandle) == DTM.TEXT_NODE) {
+                        if (sequenceTypeKindTest.getKindVal() == TEXT_KIND) {
+                           convertedResultSeq.add(nodeSetItem); 
+                        }
+                        else {
+                           String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                           throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + ". "
+                                                                                                            + "The supplied value does not match.", srcLocator); 
+                        }
+                     }
+                     else if (dtm.getNodeType(nextNodeDtmHandle) == DTM.NAMESPACE_NODE) {
+                         if (sequenceTypeKindTest.getKindVal() == NAMESPACE_NODE_KIND) {
+                            convertedResultSeq.add(nodeSetItem); 
+                         }
+                         else {
+                            String dataTypeStr = (sequenceTypeNewXPathExprStr != null) ? sequenceTypeNewXPathExprStr : sequenceTypeXPathExprStr;
+                            throw new TransformerException("XTTE0570 : The required item type of an XML instance node is " + dataTypeStr + ". "
+                                                                                                             + "The supplied value does not match.", srcLocator); 
+                         }
+                     }
+                     else {
+                        convertedResultSeq.add(nodeSetItem); 
+                     }
+                  }
+               }
+               else {
+                  if (sequenceTypeNewXPathExprStr == null) {
+                     sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr;  
+                  }
+                  
+                  if (!((xctxt == null) && ((seqExpectedTypeDataInp != null) && 
+                                                               (seqExpectedTypeDataInp.getSequenceTypeKindTest() == null)))) {
+                     String nodeStrVal = nodeSetItem.str();
+                     XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, 
+                                                                                                                    seqExpectedTypeDataInp, xctxt);                       
+                     convertedResultSeq.add(xObject);
+                  }
+                  else {
+                     throw new TransformerException("XTTE0570 : The source xdm sequence cannot be cast "
+                                                                                         + "to the provided sequence type.", srcLocator); 
+                  }
+               }
+            }
+            
+            result = convertedResultSeq;
+        }
+        
+        return result;
+    }
+    
+    /**
+     * This method casts a provided XDM evaluated sequence, to another type 
+     * specified by an xdm sequence type expression.
+     */
+    private static XObject castResultSequenceInstance(XObject srcValue,
+                                                                    String sequenceTypeXPathExprStr,
+                                                                    SequenceTypeData seqExpectedTypeDataInp, XPathContext xctxt,
+                                                                    SourceLocator srcLocator, int expectedType,
+                                                                    int itemTypeOccurenceIndicator) throws TransformerException {
+        
+        XObject result = null;
+        
+        ResultSequence srcResultSeq = (ResultSequence)srcValue;
+        
+        int seqLen = srcResultSeq.size();
+        
+        if ((seqLen > 0) && (expectedType == EMPTY_SEQUENCE)) {
+           throw new TransformerException("XTTE0570 : The sequence doesn't conform to an expected type empty-sequence(). "
+                                                                                               + "The supplied sequence has size " + seqLen + ".", srcLocator);  
+        }
+        else if ((seqLen > 1) && ((itemTypeOccurenceIndicator == 0) || (itemTypeOccurenceIndicator == 
+                                                                                                OccurenceIndicator.ZERO_OR_ONE))) {
+            throw new TransformerException("XTTE0570 : A sequence of size " + seqLen + ", cannot be cast to a type " 
+                                                                                                                + sequenceTypeXPathExprStr + ".", srcLocator); 
+        }
+        else {
+            String sequenceTypeNewXPathExprStr = null;
+            if (sequenceTypeXPathExprStr != null) {
+                if (sequenceTypeXPathExprStr.endsWith(Q_MARK) || sequenceTypeXPathExprStr.endsWith(STAR) || 
+                                                                                                sequenceTypeXPathExprStr.endsWith(PLUS)) {
+                   sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
+                }
+            }
+            
+            ResultSequence convertedResultSeq = new ResultSequence();
+            
+            for (int idx = 0; idx < srcResultSeq.size(); idx++) {
+               XObject seqItem = (XObject)(srcResultSeq.item(idx));                       
+               XObject convertedSeqItem = convertXDMValueToAnotherType(seqItem, sequenceTypeNewXPathExprStr, 
+                                                                                                         seqExpectedTypeDataInp, xctxt);
+               convertedResultSeq.add(convertedSeqItem);
+            }
+            
+            result = convertedResultSeq; 
+        }
+        
+        return result;
+    }
 
 }
diff --git a/src/org/apache/xpath/operations/InstanceOf.java b/src/org/apache/xpath/operations/InstanceOf.java
new file mode 100644
index 00000000..f11dce1f
--- /dev/null
+++ b/src/org/apache/xpath/operations/InstanceOf.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.composite.SequenceTypeData;
+import org.apache.xpath.composite.SequenceTypeSupport;
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The XPath 3.1 "instance of" operation.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class InstanceOf extends Operation
+{
+
+   private static final long serialVersionUID = -5941900193967481806L;
+
+   /**
+   * Apply the operation to two operands, and return the result.
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right) 
+                                                 throws javax.xml.transform.TransformerException
+  {
+      boolean isInstanceOf = SequenceTypeSupport.isInstanceOf(left, (SequenceTypeData)right);
+      
+      return isInstanceOf ? XBoolean.S_TRUE : XBoolean.S_FALSE;
+  }
+}
diff --git a/tests/instanceof_expr/gold/test1.out b/tests/instanceof_expr/gold/test1.out
new file mode 100644
index 00000000..c8758d93
--- /dev/null
+++ b/tests/instanceof_expr/gold/test1.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>true</one>
+  <two>true</two>
+  <three>true</three>
+  <four>true</four>
+  <five>true</five>
+  <six>false</six>
+  <seven>true</seven>
+  <eight>true</eight>
+  <nine>false</nine>
+  <ten>false</ten>
+  <eleven>false</eleven>
+  <twelve>false</twelve>
+</result>
diff --git a/tests/instanceof_expr/gold/test2.out b/tests/instanceof_expr/gold/test2.out
new file mode 100644
index 00000000..51b207bd
--- /dev/null
+++ b/tests/instanceof_expr/gold/test2.out
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?><result nodeCount="9">
+  <node position="1" type="text" name="NA">
+    <val/>
+  </node>
+  <node position="2" type="element" name="val1">
+    <val>1</val>
+  </node>
+  <node position="3" type="attribute" name="attr1">
+    <val>a</val>
+  </node>
+  <node position="4" type="text" name="NA">
+    <val>1</val>
+  </node>
+  <node position="5" type="text" name="NA">
+    <val/>
+  </node>
+  <node position="6" type="element" name="val2">
+    <val>2</val>
+  </node>
+  <node position="7" type="attribute" name="attr1">
+    <val>b</val>
+  </node>
+  <node position="8" type="text" name="NA">
+    <val>2</val>
+  </node>
+  <node position="9" type="text" name="NA">
+    <val/>
+  </node>
+</result>
diff --git a/tests/instanceof_expr/test1.xsl b/tests/instanceof_expr/test1.xsl
new file mode 100644
index 00000000..bb5bcc8d
--- /dev/null
+++ b/tests/instanceof_expr/test1.xsl
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 case, to test XPath 3.1 "instance of" 
+         expression. -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="seq1" select="(5, 6)"/>
+    
+    <xsl:template match="/info">       
+       <result>
+         <one>
+            <xsl:value-of select="5 instance of xs:integer"/>
+         </one>
+         <two>
+            <xsl:value-of select="5 instance of xs:decimal"/>
+         </two>
+         <three>            
+            <xsl:value-of select="$seq1 instance of xs:integer+"/>
+         </three>
+         <four>
+	        <xsl:value-of select=". instance of element()"/>
+         </four>
+         <five>
+	        <xsl:value-of select="* instance of element()+"/>
+         </five>
+         <six>
+	        <xsl:value-of select="* instance of element(val)+"/>
+         </six>
+         <seven>
+	        <xsl:value-of select="//@* instance of attribute()+"/>
+         </seven>
+         <eight>
+	        <xsl:value-of select="//@* instance of attribute(attr1)+"/>
+         </eight>
+         <nine>
+	        <xsl:value-of select="//@* instance of xs:integer+"/>
+         </nine>
+         <ten>
+	        <xsl:value-of select="* instance of xs:integer+"/>
+         </ten>
+         <eleven>
+	        <xsl:value-of select="$seq1 instance of element()+"/>
+         </eleven>
+         <twelve>
+	        <xsl:value-of select="5 instance of element()"/>
+         </twelve>
+       </result>
+    </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/instanceof_expr/test1_a.xml b/tests/instanceof_expr/test1_a.xml
new file mode 100644
index 00000000..f135be3d
--- /dev/null
+++ b/tests/instanceof_expr/test1_a.xml
@@ -0,0 +1,7 @@
+<info>
+  <val1 attr1="a">1</val1>
+  <val2 attr1="b">2</val2>
+  <val3 attr1="c">3</val3>
+  <val4 attr1="d">4</val4>
+  <val5 attr1="e">5</val5>
+</info>
\ No newline at end of file
diff --git a/tests/instanceof_expr/test1_b.xml b/tests/instanceof_expr/test1_b.xml
new file mode 100644
index 00000000..a9203348
--- /dev/null
+++ b/tests/instanceof_expr/test1_b.xml
@@ -0,0 +1,4 @@
+<info>
+  <val1 attr1="a">1</val1>
+  <val2 attr1="b">2</val2>
+</info>
\ No newline at end of file
diff --git a/tests/instanceof_expr/test2.xsl b/tests/instanceof_expr/test2.xsl
new file mode 100644
index 00000000..5ebb24ed
--- /dev/null
+++ b/tests/instanceof_expr/test2.xsl
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+   
+    <!-- use with test1_b.xml -->
+   
+    <!-- An XSLT stylesheet test case, to test XPath 3.1 "instance of" 
+         expression. -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="var1" select="/info//* | /info//@* | /info//text()"/>
+    
+    <xsl:template match="/">       
+       <result nodeCount="{count($var1)}">
+          <xsl:for-each select="$var1">
+             <node position="{position()}">
+                <xsl:choose>
+                    <xsl:when test=". instance of element()">
+                       <xsl:attribute name="type">element</xsl:attribute>
+                       <xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
+                       <val><xsl:value-of select="normalize-space(.)"/></val>
+                    </xsl:when>
+                    <xsl:when test=". instance of attribute()">
+                       <xsl:attribute name="type">attribute</xsl:attribute>
+                       <xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
+                       <val><xsl:value-of select="normalize-space(.)"/></val>
+                    </xsl:when>
+                    <xsl:when test=". instance of text()">
+                       <xsl:attribute name="type">text</xsl:attribute>
+                       <xsl:attribute name="name">NA</xsl:attribute>
+                       <val><xsl:value-of select="normalize-space(.)"/></val>
+                    </xsl:when>
+                </xsl:choose>
+             </node>
+          </xsl:for-each>
+       </result>
+    </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/org/apache/xalan/xpath3/InstanceOfExprTests.java b/tests/org/apache/xalan/xpath3/InstanceOfExprTests.java
new file mode 100644
index 00000000..3672f5d5
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/InstanceOfExprTests.java
@@ -0,0 +1,70 @@
+/*
+ * 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.xpath3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.apache.xalan.xslt3.XSLConstants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XPath 3.1 "instance of" expression test cases.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class InstanceOfExprTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "instanceof_expr/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "instanceof_expr/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 xslInstanceOfExprTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslInstanceOfExprTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 1a6272a5..c554db94 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -43,6 +43,7 @@ import org.apache.xalan.xpath3.FnUnparsedTextTests;
 import org.apache.xalan.xpath3.ForExprTests;
 import org.apache.xalan.xpath3.IfExprTests;
 import org.apache.xalan.xpath3.InlineFunctionItemExprTests;
+import org.apache.xalan.xpath3.InstanceOfExprTests;
 import org.apache.xalan.xpath3.LetExprTests;
 import org.apache.xalan.xpath3.NodeComparisonTests;
 import org.apache.xalan.xpath3.QuantifiedExprTests;
@@ -92,7 +93,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
                 SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
                 TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class,
-                XslAttributeAsTests.class })
+                XslAttributeAsTests.class, InstanceOfExprTests.class })
 public class AllXsl3Tests {
 
 }


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