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/04 11:40:41 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing improvements to xpath 3.1 sequence type expressions, now having support for sequence type expressions involving element(), attribute() and few other xpath KindTest expressions. also committing few new relevant working test cases as well.

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 f1eb0bfd committing improvements to xpath 3.1 sequence type expressions, now having support for sequence type expressions involving element(), attribute() and few other xpath KindTest expressions. also committing few new relevant working test cases as well.
     new d4736aa0 Merge pull request #74 from mukulga/xalan-j_xslt3.0_mukul
f1eb0bfd is described below

commit f1eb0bfd20049c1f40a5f5bf93d497dead092468
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Sep 4 17:05:39 2023 +0530

    committing improvements to xpath 3.1 sequence type expressions, now having support for sequence type expressions involving element(), attribute() and few other xpath KindTest expressions. also committing few new relevant working test cases as well.
---
 src/org/apache/xalan/templates/ElemCopyOf.java     |  11 +-
 src/org/apache/xpath/compiler/XPathParser.java     | 193 +++++++++++++--
 .../apache/xpath/composite/SequenceTypeData.java   |  12 +
 .../xpath/composite/SequenceTypeKindTest.java      |  85 +++++++
 .../xpath/composite/SequenceTypeSupport.java       | 269 ++++++++++++++++++---
 .../xpath/composite/XPathSequenceTypeExpr.java     |  13 +-
 src/org/apache/xpath/xs/types/XSDate.java          |   3 +
 src/org/apache/xpath/xs/types/XSDateTime.java      |   3 +
 .../apache/xpath/xs/types/XSDayTimeDuration.java   |   6 +-
 src/org/apache/xpath/xs/types/XSDuration.java      |   6 +-
 .../apache/xpath/xs/types/XSYearMonthDuration.java |   3 +
 .../apache/xalan/xslt3/XslAttributeAsTests.java    |  61 +++++
 tests/xsl_attribute_as/gold/test4.out              |  23 ++
 tests/xsl_attribute_as/gold/test5.out              |   7 +
 tests/xsl_attribute_as/gold/test6.out              |   1 +
 tests/xsl_attribute_as/gold/test7.out              |   1 +
 tests/xsl_attribute_as/gold/test8.out              |   7 +
 tests/xsl_attribute_as/test1_b.xml                 |   7 +
 tests/xsl_attribute_as/test1_c.xml                 |   7 +
 tests/xsl_attribute_as/test1_d.xml                 |   7 +
 tests/xsl_attribute_as/test1_e.xml                 |   7 +
 tests/xsl_attribute_as/test4.xsl                   |  51 ++++
 tests/xsl_attribute_as/test5.xsl                   |  41 ++++
 tests/xsl_attribute_as/test6.xsl                   |  46 ++++
 tests/xsl_attribute_as/test7.xsl                   |  41 ++++
 tests/xsl_attribute_as/test8.xsl                   |  43 ++++
 tests/xsl_attribute_as/test9.xsl                   |  47 ++++
 27 files changed, 936 insertions(+), 65 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemCopyOf.java b/src/org/apache/xalan/templates/ElemCopyOf.java
index 373bbc48..a747e35d 100644
--- a/src/org/apache/xalan/templates/ElemCopyOf.java
+++ b/src/org/apache/xalan/templates/ElemCopyOf.java
@@ -38,7 +38,9 @@ import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
 import org.apache.xpath.xs.types.XSNumericType;
+import org.apache.xpath.xs.types.XSString;
 import org.apache.xpath.xs.types.XSUntyped;
 import org.apache.xpath.xs.types.XSUntypedAtomic;
 import org.xml.sax.SAXException;
@@ -304,13 +306,20 @@ public class ElemCopyOf extends ElemTemplateElement
       for (int idx = 0; idx < resultSequence.size(); idx++) {             
          XObject sequenceItem = resultSequence.item(idx);
          
-         if (sequenceItem.getType() == XObject.CLASS_STRING) {
+         if (sequenceItem instanceof XString) {
              String str = sequenceItem.str();
              serializationHandler.characters(str.toCharArray(), 0, str.length());
              if (idx < (resultSequence.size() - 1)) {                     
                 serializationHandler.characters(spaceCharArr, 0, 1);
              }
          }
+         else if (sequenceItem instanceof XSString) {
+             String str = ((XSString)sequenceItem).stringValue();
+             serializationHandler.characters(str.toCharArray(), 0, str.length());
+             if (idx < (resultSequence.size() - 1)) {                     
+                serializationHandler.characters(spaceCharArr, 0, 1);
+             }
+         }
          else if (sequenceItem.getType() == XObject.CLASS_NUMBER) {
              String str = ((XNumber)sequenceItem).str();
              serializationHandler.characters(str.toCharArray(), 0, str.length());
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 79d0c75c..18325b6c 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -38,6 +38,7 @@ import org.apache.xpath.composite.IfExpr;
 import org.apache.xpath.composite.LetExpr;
 import org.apache.xpath.composite.LetExprVarBinding;
 import org.apache.xpath.composite.QuantifiedExpr;
+import org.apache.xpath.composite.SequenceTypeKindTest;
 import org.apache.xpath.composite.SequenceTypeSupport;
 import org.apache.xpath.composite.SimpleSequenceConstructor;
 import org.apache.xpath.composite.XPathSequenceTypeExpr;
@@ -795,6 +796,112 @@ public class XPathParser
       throw new RuntimeException(fMsg);
     }
   }
+  
+  /**
+   * This method helps to implement, XPath 3.1 sequence type expressions.
+   */
+  private void setSequenceTypeOccurenceIndicator(XPathSequenceTypeExpr xpathSequenceTypeExpr) throws TransformerException {
+      if (tokenIs(SequenceTypeSupport.Q_MARK)) {
+         xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
+                                                                                 OccurenceIndicator.ZERO_OR_ONE);
+         nextToken();
+      }
+      else if (tokenIs(SequenceTypeSupport.STAR)) {
+         xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
+                                                                                 OccurenceIndicator.ZERO_OR_MANY);
+         nextToken();
+      }
+      else if (tokenIs(SequenceTypeSupport.PLUS)) {
+         xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
+                                                                                 OccurenceIndicator.ONE_OR_MANY);
+         nextToken();
+      }
+      else {
+         throw new javax.xml.transform.TransformerException("XPST0051 A sequence type occurence indicator '" + m_token + "', is not recognized."); 
+      }
+   }
+  
+  /**
+   * Given an XML node's raw name like abc:pqr, this method returns
+   * a String array having the XML name components 'abc' and 'pqr'
+   * within individual array elements.
+   */
+   private String[] getXmlNamespaceStrComponents(String xmlRawName) {     
+      String[] xmlNamespaceStrParts = new String[2];
+      
+      int idx = xmlRawName.lastIndexOf(':');             
+      String localName = null;
+      String nsUri = null;
+      if (idx != -1) {
+         nsUri = xmlRawName.substring(0, idx);
+         localName = xmlRawName.substring(idx + 1);                
+      }
+      else {
+         localName = xmlRawName;  
+      }
+      
+      xmlNamespaceStrParts[0] = localName;
+      xmlNamespaceStrParts[1] = nsUri;
+      
+      return xmlNamespaceStrParts; 
+   }
+   
+   /**
+    * This method helps to implement, XPath 3.1 sequence type expressions.
+    */
+   private SequenceTypeKindTest constructSeqTypeKindTestForXmlNodes(XPathSequenceTypeExpr 
+                                                                                  xpathSequenceTypeExpr, int nodeType) throws TransformerException {
+
+       SequenceTypeKindTest sequenceTypeKindTest = new SequenceTypeKindTest();
+
+       sequenceTypeKindTest.setKindVal(nodeType);          
+       nextToken();
+       consumeExpected('(');
+       String nodeKindTestStr = "";
+       while (!tokenIs(")") && m_token != null) {
+           nodeKindTestStr += m_token;
+           nextToken();
+       }
+       if (tokenIs(')')) {
+           if (getTokenRelative(0) == null) {
+               nextToken();                
+           }
+           else if (getTokenRelative(1) == null) {
+               nextToken();                
+               setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr);
+           }
+           else {
+               throw new javax.xml.transform.TransformerException("XPST0051 : The sequence type expression is "
+                                                                                                      + "not well-formed."); 
+           }
+       }
+       else {
+           throw new javax.xml.transform.TransformerException("XPST0051 : The sequence type expression is "
+                                                                                                  + "not well-formed. The expected token ')' within "
+                                                                                                  + "a sequence type expression is not present.");  
+       }
+
+       String[] seqTypeSubParts = nodeKindTestStr.split(",");
+       if (seqTypeSubParts.length == 1) {
+           String[] nsParts = getXmlNamespaceStrComponents(seqTypeSubParts[0]);
+           sequenceTypeKindTest.setNodeLocalName(nsParts[0]);
+           sequenceTypeKindTest.setNodeNsUri(nsParts[1]);
+       }
+       else if (seqTypeSubParts.length == 2) {
+           String[] nodeNsParts = getXmlNamespaceStrComponents(seqTypeSubParts[0]);
+           String[] nodeDataTypeParts = getXmlNamespaceStrComponents(seqTypeSubParts[1]);
+           sequenceTypeKindTest.setNodeLocalName(nodeNsParts[0]);
+           sequenceTypeKindTest.setNodeNsUri(nodeNsParts[1]);
+           sequenceTypeKindTest.setDataTypeName(nodeDataTypeParts[0]);
+           sequenceTypeKindTest.setDataTypeUri(nodeDataTypeParts[1]);
+       }
+       else if (seqTypeSubParts.length > 2) {
+           throw new javax.xml.transform.TransformerException("XPST0051 : The sequence type expression is "
+                                                                                                    + "not well-formed."); 
+       }
+
+       return sequenceTypeKindTest;
+  }
 
   /**
    * Notify the user of an error, and probably throw an
@@ -3580,6 +3687,8 @@ public class XPathParser
       
       XPathSequenceTypeExpr xpathSequenceTypeExpr = new XPathSequenceTypeExpr();
       
+      SequenceTypeKindTest sequenceTypeKindTest = null;
+      
       if (tokenIs("empty-sequence") && lookahead('(', 1) && lookahead(')', 2)) {
          xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.EMPTY_SEQUENCE);
          consumeExpected("empty-sequence");
@@ -3628,33 +3737,73 @@ public class XPathParser
                xpathSequenceTypeExpr.setSequenceType(SequenceTypeSupport.XS_DAYTIME_DURATION);
                break;
             default :
-               throw new XPathProcessorException("XPST0051 An XML Schema type 'xs:" + m_token + "' is not "
-                                                                             + "recognized, within the provided sequence type expression.");        
+               throw new javax.xml.transform.TransformerException("XPST0051 An XML Schema type 'xs:" + m_token + "' is not "
+                                                                                        + "recognized, within the provided sequence type expression.");        
          }
          
          nextToken();
          
          if ((m_token != null) && (xpathSequenceTypeExpr.getSequenceType() > 0)) {
-            if (tokenIs(SequenceTypeSupport.Q_MARK)) {
-               xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
-                                                                                     OccurenceIndicator.ZERO_OR_ONE);
-               nextToken();
-            }
-            else if (tokenIs(SequenceTypeSupport.STAR)) {
-               xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
-                                                                                     OccurenceIndicator.ZERO_OR_MANY);
-               nextToken();
-            }
-            else if (tokenIs(SequenceTypeSupport.PLUS)) {
-               xpathSequenceTypeExpr.setItemTypeOccurrenceIndicator(SequenceTypeSupport.
-                                                                                     OccurenceIndicator.ONE_OR_MANY);
-               nextToken();
-            }
-            else {
-               throw new XPathProcessorException("XPST0051 A sequence type occurence indicator '" + m_token + "', is not recognized."); 
-            }
-         }
-         
+            setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr);
+         }         
+      }
+      else if (tokenIs("element")) {
+          sequenceTypeKindTest = constructSeqTypeKindTestForXmlNodes(xpathSequenceTypeExpr, 
+                                                                                        SequenceTypeSupport.ELEMENT_KIND);          
+          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);          
+      }
+      else if (tokenIs("attribute")) {
+          sequenceTypeKindTest = constructSeqTypeKindTestForXmlNodes(xpathSequenceTypeExpr, 
+                                                                                        SequenceTypeSupport.ATTRIBUTE_KIND);          
+          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+      }
+      else if (tokenIs("text")) {
+          sequenceTypeKindTest = new SequenceTypeKindTest();
+          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.TEXT_KIND);          
+          nextToken();
+          consumeExpected('(');
+          consumeExpected(')');
+          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+          if (m_token != null) {
+             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr); 
+          }          
+      }
+      else if (tokenIs("namespace-node")) {
+          sequenceTypeKindTest = new SequenceTypeKindTest();
+          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.NAMESPACE_NODE_KIND);          
+          nextToken();
+          consumeExpected('(');
+          consumeExpected(')');
+          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+          if (m_token != null) {
+             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr); 
+          }
+      }
+      else if (tokenIs("node")) { 
+          sequenceTypeKindTest = new SequenceTypeKindTest();
+          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.NODE_KIND);          
+          nextToken();
+          consumeExpected('(');
+          consumeExpected(')');
+          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+          if (m_token != null) {
+             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr);  
+          }
+      }
+      else if (tokenIs("item")) {
+          sequenceTypeKindTest = new SequenceTypeKindTest();
+          sequenceTypeKindTest.setKindVal(SequenceTypeSupport.ITEM_KIND);          
+          nextToken();
+          consumeExpected('(');
+          consumeExpected(')');
+          xpathSequenceTypeExpr.setSequenceTypeKindTest(sequenceTypeKindTest);
+          if (m_token != null) {
+             setSequenceTypeOccurenceIndicator(xpathSequenceTypeExpr);  
+          }
+      }            
+      else {
+          throw new javax.xml.transform.TransformerException("XPST0051 The sequence type '" + m_token + "' is not "
+                                                                                                   + "recognized, within the provided sequence type expression."); 
       }
       
       m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
diff --git a/src/org/apache/xpath/composite/SequenceTypeData.java b/src/org/apache/xpath/composite/SequenceTypeData.java
index 5ec295a2..24d73cf7 100644
--- a/src/org/apache/xpath/composite/SequenceTypeData.java
+++ b/src/org/apache/xpath/composite/SequenceTypeData.java
@@ -33,9 +33,13 @@ import org.apache.xpath.objects.XObject;
  */
 public class SequenceTypeData extends XObject {
     
+    private static final long serialVersionUID = -8207360998434418776L;
+
     private int fSequenceType;
     
     private int fItemTypeOccurrenceIndicator;
+    
+    private SequenceTypeKindTest sequenceTypeKindTest; 
 
     public int getSequenceType() {
         return fSequenceType;
@@ -53,4 +57,12 @@ public class SequenceTypeData extends XObject {
         this.fItemTypeOccurrenceIndicator = itemTypeOccurrenceIndicator;
     }
 
+    public SequenceTypeKindTest getSequenceTypeKindTest() {
+        return sequenceTypeKindTest;
+    }
+
+    public void setSequenceTypeKindTest(SequenceTypeKindTest sequenceTypeKindTest) {
+        this.sequenceTypeKindTest = sequenceTypeKindTest;
+    }
+
 }
diff --git a/src/org/apache/xpath/composite/SequenceTypeKindTest.java b/src/org/apache/xpath/composite/SequenceTypeKindTest.java
new file mode 100644
index 00000000..6eefec74
--- /dev/null
+++ b/src/org/apache/xpath/composite/SequenceTypeKindTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.xpath.composite;
+
+/**
+ * An object of this class stores, an XSLT transformation run-time
+ * information for an occurrence of a XPath 3.1 sequence type
+ * kind test (for e.g, element(), element(elemName), attribute(), 
+ * element(elemName, typeName)* etc. 
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class SequenceTypeKindTest {
+    
+    private int kindVal;
+    
+    // for XML element and attribute nodes
+    private String nodeLocalName;
+    
+    // for XML element and attribute nodes
+    private String nodeNsUri;
+    
+    // data type's name (for e.g, string, integer etc)
+    private String dataTypeLocalName;
+    
+    // XML namespace uri of the data type (for e.g, http://www.w3.org/2001/XMLSchema)
+    private String dataTypeUri;
+
+    public int getKindVal() {
+        return kindVal;
+    }
+
+    public void setKindVal(int kindVal) {
+        this.kindVal = kindVal;
+    }
+
+    public String getNodeLocalName() {
+        return nodeLocalName;
+    }
+
+    public void setNodeLocalName(String nodeLocalName) {
+        this.nodeLocalName = nodeLocalName;
+    }
+
+    public String getNodeNsUri() {
+        return nodeNsUri;
+    }
+
+    public void setNodeNsUri(String nodeNsUri) {
+        this.nodeNsUri = nodeNsUri;
+    }
+
+    public String getDataTypeName() {
+        return dataTypeLocalName;
+    }
+
+    public void setDataTypeName(String dataTypeName) {
+        this.dataTypeLocalName = dataTypeName;
+    }
+    
+    public String getDataTypeUri() {
+        return dataTypeUri;
+    }
+
+    public void setDataTypeUri(String dataTypeUri) {
+        this.dataTypeUri = dataTypeUri;
+    }
+
+}
diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
index 6a23c2eb..dae54636 100644
--- a/src/org/apache/xpath/composite/SequenceTypeSupport.java
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -19,8 +19,10 @@ package org.apache.xpath.composite;
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
 
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.ResultSequence;
@@ -95,6 +97,20 @@ public class SequenceTypeSupport {
     public static int XS_DOUBLE = 14;
     
     public static int XS_FLOAT = 15;
+    
+        
+    public static int ELEMENT_KIND = 101;
+    
+    public static int ATTRIBUTE_KIND = 102;
+    
+    public static int TEXT_KIND = 103;
+    
+    public static int NAMESPACE_NODE_KIND = 104;
+    
+    public static int NODE_KIND = 105;
+    
+    public static int ITEM_KIND = 106;
+    
         
     public static class OccurenceIndicator {
        // Represents the sequence type occurrence indicator '?'
@@ -114,9 +130,15 @@ public class SequenceTypeSupport {
     public static String PLUS = "+";
     
     /**
-     * This method converts/casts an xdm source value represented by an XObject
-     * object instance, to a value of another type. This method is called 
-     * recursively at certain places.
+     * This method converts/casts an XPath 3.1 xdm source value represented by an
+     * XObject object instance, to a value of another xdm data type.
+     * 
+     * For XPath sequence type expressions that represent KindTest (i.e,
+     * element(), attribute() etc), this method only checks whether an XML input
+     * item conforms with the provided KindTest sequence type expression, and
+     * returns an input value unchanged.  
+     * 
+     * This method is called recursively at certain places.
      *  
      * @param srcValue                     an XObject object instance that represents a
      *                                     source xdm value. 
@@ -150,14 +172,18 @@ public class SequenceTypeSupport {
             
             int expectedType = seqExpectedTypeData.getSequenceType();            
             int itemTypeOccurenceIndicator = seqExpectedTypeData.getItemTypeOccurrenceIndicator();
+            SequenceTypeKindTest sequenceTypeKindTest = seqExpectedTypeData.getSequenceTypeKindTest();
             
             if (srcValue instanceof XString) {
                 String srcStrVal = ((XString)srcValue).str();
                 
                 if (expectedType == STRING) {
-                   // The source and expected data types are same. Return the original value unchanged.
                    result = srcValue; 
                 }
+                else if (sequenceTypeKindTest != null) {                   
+                   result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                    "xs:string", sequenceTypeXPathExprStr);
+                }
                 else {
                    result = convertStringValueToAnExpectedType(srcStrVal, expectedType);
                 }
@@ -166,28 +192,61 @@ public class SequenceTypeSupport {
                String srcStrVal = ((XSString)srcValue).stringValue();
                
                if (expectedType == STRING) {
-                  // The source and expected data types are same. Return the original value unchanged.
                   result = srcValue; 
                }
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                   "xs:string", sequenceTypeXPathExprStr);
+               }
                else {
                   result = convertStringValueToAnExpectedType(srcStrVal, expectedType);
                }
             }
             else if (srcValue instanceof XNumber) {
                XSDouble xsDouble = new XSDouble(((XNumber)srcValue).num());
-               result = performXDMNumericTypeConversion(xsDouble, expectedType);
+               String srcStrVal = xsDouble.stringValue(); 
+               
+               if (expectedType == XS_DOUBLE) {
+                  result = srcValue; 
+               }
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                   "xs:double", sequenceTypeXPathExprStr);
+               }
+               else {
+                  result = performXDMNumericTypeConversion(xsDouble, expectedType);
+               }
             }
             else if (srcValue instanceof XSNumericType) {
-               result = performXDMNumericTypeConversion((XSNumericType)srcValue, expectedType); 
+               XSNumericType xsNumericType = (XSNumericType)srcValue;
+               
+               try {
+                   result = performXDMNumericTypeConversion(xsNumericType, expectedType);
+               }
+               catch (TransformerException ex1) {
+                  if (sequenceTypeKindTest != null) {
+                     String srcStrVal = xsNumericType.stringValue();
+                     try {
+                        result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                         xsNumericType.stringType(), sequenceTypeXPathExprStr);
+                     }
+                     catch (TransformerException ex2) {
+                        throw ex2; 
+                     }
+                  }
+                  else {
+                     throw ex1;   
+                  }
+               }
             }
             else if (srcValue instanceof XBoolean) {
                String srcStrVal = ((XBoolean)srcValue).str();
                if (expectedType == BOOLEAN) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The boolean value " + srcStrVal + " cannot be "
-                                                                            + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator); 
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                    "xs:boolean", sequenceTypeXPathExprStr);
                }
             }
             else if (srcValue instanceof XSBoolean) {
@@ -195,9 +254,9 @@ public class SequenceTypeSupport {
                if (expectedType == BOOLEAN) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The boolean value " + srcStrVal + " cannot be "
-                                                                             + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator); 
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                    "xs:boolean", sequenceTypeXPathExprStr);
                } 
             }
             else if (srcValue instanceof XSDate) {
@@ -205,9 +264,9 @@ public class SequenceTypeSupport {
                if (expectedType == XS_DATE) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The xs:date value " + srcStrVal + " cannot be "
-                                                                            + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);   
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                    "xs:date", sequenceTypeXPathExprStr);
                } 
             }
             else if (srcValue instanceof XSDateTime) {
@@ -215,19 +274,19 @@ public class SequenceTypeSupport {
                if (expectedType == XS_DATETIME) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The xs:dateTime value " + srcStrVal + " cannot be "
-                                                                                + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);     
-               } 
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                    "xs:dateTime", sequenceTypeXPathExprStr);
+               }
             }
             else if (srcValue instanceof XSTime) {
                String srcStrVal = ((XSTime)srcValue).stringValue();
                if (expectedType == XS_TIME) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The xs:time value " + srcStrVal + " cannot be "
-                                                                            + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                   "xs:time", sequenceTypeXPathExprStr);
                }
             }
             else if (srcValue instanceof XSDuration) {
@@ -235,29 +294,29 @@ public class SequenceTypeSupport {
                if (expectedType == XS_DURATION) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The xs:duration value " + srcStrVal + " cannot be "
-                                                                                + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                   "xs:duration", sequenceTypeXPathExprStr);
                } 
             }
             else if (srcValue instanceof XSDayTimeDuration) {
-               String srcStrVal = ((XSDayTimeDuration)srcValue).stringValue();
+               String srcStrVal = ((XSDayTimeDuration)srcValue).stringValue();     
                if (expectedType == XS_DAYTIME_DURATION) {
                   result = srcValue; 
                }
-               else {
-                  throw new TransformerException("XTTE0570 : The xs:dayTimeDuration value " + srcStrVal + " cannot be "
-                                                                                 + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                   "xs:dayTimeDuration", sequenceTypeXPathExprStr);
                } 
             }
             else if (srcValue instanceof XSYearMonthDuration) {
-               String srcStrVal = ((XSYearMonthDuration)srcValue).stringValue();
+               String srcStrVal = ((XSYearMonthDuration)srcValue).stringValue();      
                if (expectedType == XS_YEARMONTH_DURATION) {
                   result = srcValue; 
                }
-               else {
-                   throw new TransformerException("XTTE0570 : The xs:yearMonthDuration value " + srcStrVal + " cannot be "
-                                                                                  + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + ".", srcLocator);       
+               else if (sequenceTypeKindTest != null) {
+                  result = performXdmItemTypeNormalizationOnAtomicType(sequenceTypeKindTest, srcValue, srcStrVal, 
+                                                                                                   "xs:yearMonthDuration", sequenceTypeXPathExprStr);
                } 
             }
             else if (srcValue instanceof XSUntyped) {
@@ -281,6 +340,8 @@ public class SequenceTypeSupport {
                 else { 
                     ResultSequence convertedResultSeq = new ResultSequence();
                     
+                    DTMManager dtmMgr = (DTMManager)xctxt;
+                    
                     DTMIterator dtmIter = xdmNodeSet.iterRaw();
                     
                     int nextNodeDtmHandle;
@@ -295,9 +356,91 @@ public class SequenceTypeSupport {
                           sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr.substring(0, sequenceTypeXPathExprStr.length() - 1);  
                        }
                        
-                       XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, xctxt);
-                       
-                       convertedResultSeq.add(xObject);
+                       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;  
+                          }                          
+                          XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, xctxt);                       
+                          convertedResultSeq.add(xObject);
+                       }
                     }
                     
                     result = convertedResultSeq;
@@ -327,7 +470,7 @@ public class SequenceTypeSupport {
                     ResultSequence convertedResultSeq = new ResultSequence();
                     
                     for (int idx = 0; idx < srcResultSeq.size(); idx++) {
-                       XObject seqItem = (XObject)(srcResultSeq.item(idx));
+                       XObject seqItem = (XObject)(srcResultSeq.item(idx));                       
                        XObject convertedSeqItem = convertXDMValueToAnotherType(seqItem, sequenceTypeNewXPathExprStr, xctxt);
                        convertedResultSeq.add(convertedSeqItem);
                     }
@@ -337,7 +480,12 @@ public class SequenceTypeSupport {
             }
         }
         catch (TransformerException ex) {
-            throw new TransformerException(ex.getMessage(), srcLocator); 
+            throw ex; 
+        }
+        catch (Exception ex) {
+            String srcStrVal = XslTransformEvaluationHelper.getStrVal(srcValue); 
+            throw new TransformerException("XTTE0570 : The source value '" + srcStrVal + "' cannot be cast "
+                                                                                    + "to a type " + sequenceTypeXPathExprStr + ".", srcLocator); 
         }
         
         return result;
@@ -381,6 +529,9 @@ public class SequenceTypeSupport {
                                                                                                   + "cast to a type " + getDataTypeNameFromIntValue(expectedType) + "."); 
             }
         }
+        catch (TransformerException ex) {
+            throw ex;    
+        }
         catch (Exception ex) {
             throw new TransformerException("XTTE0570 : The string value '" + srcStrVal + "' cannot be cast to "
                                                                                                + "a type " + getDataTypeNameFromIntValue(expectedType) + ".");
@@ -448,6 +599,9 @@ public class SequenceTypeSupport {
                                                                                                  + "to a type " + getDataTypeNameFromIntValue(expectedType) + ".");  
             }
         }
+        catch (TransformerException ex) {
+            throw ex;  
+        }
         catch (Exception ex) {
             throw new TransformerException("XTTE0570 : The numeric value " + srcStrVal + " cannot be cast "
                                                                                                + "to a type " + getDataTypeNameFromIntValue(expectedType) + ".");
@@ -512,5 +666,42 @@ public class SequenceTypeSupport {
        
        return dataTypeName;       
     }
+    
+    /**
+     * Given an XObject object instance representing an atomic data value, check whether
+     * a sequence type item() type annotation could be applied.
+     */
+    private static XObject performXdmItemTypeNormalizationOnAtomicType(SequenceTypeKindTest sequenceTypeKindTest, 
+                                                                                     XObject srcValue, String srcStrVal, 
+                                                                                     String srcDataTypeName, 
+                                                                                     String sequenceTypeXPathExprStr) throws TransformerException {
+        XObject result = null;
+        
+        if (sequenceTypeKindTest.getKindVal() == ITEM_KIND) {
+           result = srcValue;
+        }
+        else {
+           throw new TransformerException("XTTE0570 : An " + srcDataTypeName + " value '" + srcStrVal + "' cannot be cast to "
+                                                                                                   + "a type " + sequenceTypeXPathExprStr + "."); 
+        }
+        
+        return result;
+    }
+    
+    /**
+     * Check whether, two XML namespace uris are equal.
+     */
+    private static boolean isTwoXmlNamespacesEqual(String nsUr1, String nsUri2) {
+        boolean xmlNamespacesEqual = false;
+        
+        if ((nsUr1 == null) && (nsUri2 == null)) {
+           xmlNamespacesEqual = true; 
+        }
+        else if ((nsUr1 != null) && (nsUri2 != null)) {
+           xmlNamespacesEqual = nsUr1.equals(nsUri2);  
+        }
+        
+        return xmlNamespacesEqual; 
+     }
 
 }
diff --git a/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java b/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
index f70b3a16..0cad9b89 100644
--- a/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
+++ b/src/org/apache/xpath/composite/XPathSequenceTypeExpr.java
@@ -41,12 +41,15 @@ public class XPathSequenceTypeExpr extends Expression {
     private int fSequenceType;
     
     private int fItemTypeOccurrenceIndicator;
+    
+    private SequenceTypeKindTest fSequenceTypeKindTest;
 
     @Override
     public XObject execute(XPathContext xctxt) throws TransformerException {
        SequenceTypeData sequenceTypeData = new SequenceTypeData();
        
-       sequenceTypeData.setSequenceType(fSequenceType);
+       sequenceTypeData.setSequenceType(fSequenceType);       
+       sequenceTypeData.setSequenceTypeKindTest(fSequenceTypeKindTest);       
        sequenceTypeData.setItemTypeOccurrenceIndicator(fItemTypeOccurrenceIndicator);
        
        return sequenceTypeData;
@@ -79,6 +82,14 @@ public class XPathSequenceTypeExpr extends Expression {
         this.fItemTypeOccurrenceIndicator = itemTypeOccurrenceIndicator;
     }
     
+    public SequenceTypeKindTest getSequenceTypeKindTest() {
+        return fSequenceTypeKindTest;
+    }
+
+    public void setSequenceTypeKindTest(SequenceTypeKindTest sequenceTypeKindTest) {
+        this.fSequenceTypeKindTest = sequenceTypeKindTest;
+    }
+
     @Override
     public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) {
        // NO OP        
diff --git a/src/org/apache/xpath/xs/types/XSDate.java b/src/org/apache/xpath/xs/types/XSDate.java
index 90610de4..798d5ac9 100644
--- a/src/org/apache/xpath/xs/types/XSDate.java
+++ b/src/org/apache/xpath/xs/types/XSDate.java
@@ -145,6 +145,9 @@ public class XSDate extends XSCalendarType {
                                                                                   strVal + "' cannot be parsed to a xs:date value."); 
             }
         }
+        catch (TransformerException ex) {
+           throw ex;  
+        }
         catch (Exception ex) {
             throw new TransformerException("XTTE0570 : The supplied string value '" + 
                                                                                   strVal + "' cannot be parsed to a xs:date value."); 
diff --git a/src/org/apache/xpath/xs/types/XSDateTime.java b/src/org/apache/xpath/xs/types/XSDateTime.java
index 294a6c1c..e854ab4d 100644
--- a/src/org/apache/xpath/xs/types/XSDateTime.java
+++ b/src/org/apache/xpath/xs/types/XSDateTime.java
@@ -490,6 +490,9 @@ public class XSDateTime extends XSCalendarType {
             
             xsDateTime = new XSDateTime(gregorianCalendarObj, timezoneVal);
         }
+        catch (TransformerException ex) {
+            throw ex;  
+        }
         catch (Exception ex) {
             throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
                                                                                + "cannot be parsed to a xs:dateTime value."); 
diff --git a/src/org/apache/xpath/xs/types/XSDayTimeDuration.java b/src/org/apache/xpath/xs/types/XSDayTimeDuration.java
index 3c923c7f..44fbd2cd 100644
--- a/src/org/apache/xpath/xs/types/XSDayTimeDuration.java
+++ b/src/org/apache/xpath/xs/types/XSDayTimeDuration.java
@@ -189,7 +189,11 @@ public class XSDayTimeDuration extends XSDuration {
 			    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
                                                                                                      + "cannot be parsed to a xs:dayTimeDuration value.");
 			}
-		} catch (Exception ex) {
+		} 
+		catch (TransformerException ex) {
+	        throw ex;  
+	    }
+		catch (Exception ex) {
 		    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
                                                                                           + "cannot be parsed to a xs:dayTimeDuration value.");
 		}
diff --git a/src/org/apache/xpath/xs/types/XSDuration.java b/src/org/apache/xpath/xs/types/XSDuration.java
index 88bff6ab..385e7212 100644
--- a/src/org/apache/xpath/xs/types/XSDuration.java
+++ b/src/org/apache/xpath/xs/types/XSDuration.java
@@ -394,7 +394,11 @@ public class XSDuration extends XSCtrType {
                                                                                                + "cannot be parsed to a xs:duration value.");
 			}
 
-		} catch (Exception ex) {
+		} 
+		catch (TransformerException ex) {
+	        throw ex;  
+	    }
+		catch (Exception ex) {
 		    throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
                                                                                               + "cannot be parsed to a xs:duration value."); 
 		}
diff --git a/src/org/apache/xpath/xs/types/XSYearMonthDuration.java b/src/org/apache/xpath/xs/types/XSYearMonthDuration.java
index 5bf937ac..b8936e62 100644
--- a/src/org/apache/xpath/xs/types/XSYearMonthDuration.java
+++ b/src/org/apache/xpath/xs/types/XSYearMonthDuration.java
@@ -162,6 +162,9 @@ public class XSYearMonthDuration extends XSDuration {
                 }
             }
         }
+        catch (TransformerException ex) {
+           throw ex;  
+        }
         catch (Exception ex) {
            throw new TransformerException("XTTE0570 : The supplied string value '" + strVal + "' "
                                                                                          + "cannot be parsed to a xs:yearMonthDuration value."); 
diff --git a/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java b/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java
index 4b737931..4ccdbb7e 100644
--- a/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java
+++ b/tests/org/apache/xalan/xslt3/XslAttributeAsTests.java
@@ -81,5 +81,66 @@ public class XslAttributeAsTests extends XslTransformTestsUtil {
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
                                                                            new XslTestsErrorHandler());   
     }
+    
+    @Test
+    public void xslAttributeAsTest4() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslAttributeAsTest5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslAttributeAsTest6() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_d.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
+                                                                           new XslTestsErrorHandler());   
+    }
+    
+    @Test
+    public void xslAttributeAsTest7() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslAttributeAsTest8() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test8.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
+    
+    @Test
+    public void xslAttributeAsTest9() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_e.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test8.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
 
 }
diff --git a/tests/xsl_attribute_as/gold/test4.out b/tests/xsl_attribute_as/gold/test4.out
new file mode 100644
index 00000000..82d7ce4f
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test4.out
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>
+    <val>1</val>
+    <val>2</val>
+    <val>3</val>
+    <val>4</val>
+    <val>5</val>
+  </one>
+  <two>
+    <val>1</val>
+    <val>2</val>
+    <val>3</val>
+    <val>4</val>
+    <val>5</val>
+  </two>
+  <three>
+    <val>1</val>
+    <val>2</val>
+    <val>3</val>
+    <val>4</val>
+    <val>5</val>
+  </three>
+</result>
diff --git a/tests/xsl_attribute_as/gold/test5.out b/tests/xsl_attribute_as/gold/test5.out
new file mode 100644
index 00000000..b35d2c30
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test5.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <val1>1</val1>
+  <val2>2</val2>
+  <val3>3</val3>
+  <val4>4</val4>
+  <val5>5</val5>
+</result>
diff --git a/tests/xsl_attribute_as/gold/test6.out b/tests/xsl_attribute_as/gold/test6.out
new file mode 100644
index 00000000..4195357b
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test6.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result>11</result>
diff --git a/tests/xsl_attribute_as/gold/test7.out b/tests/xsl_attribute_as/gold/test7.out
new file mode 100644
index 00000000..6f8db078
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test7.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result>1 2 3 4 5</result>
diff --git a/tests/xsl_attribute_as/gold/test8.out b/tests/xsl_attribute_as/gold/test8.out
new file mode 100644
index 00000000..1a22d23f
--- /dev/null
+++ b/tests/xsl_attribute_as/gold/test8.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <valNew attr1="1">1</valNew>
+  <valNew attr1="2">2</valNew>
+  <valNew attr1="3">3</valNew>
+  <valNew attr1="4">4</valNew>
+  <valNew attr1="test val">5</valNew>
+</result>
diff --git a/tests/xsl_attribute_as/test1_b.xml b/tests/xsl_attribute_as/test1_b.xml
new file mode 100644
index 00000000..7cd599b2
--- /dev/null
+++ b/tests/xsl_attribute_as/test1_b.xml
@@ -0,0 +1,7 @@
+<info>
+  <val>1</val>
+  <val>2</val>
+  <val>3</val>
+  <val>4</val>
+  <val>5</val>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test1_c.xml b/tests/xsl_attribute_as/test1_c.xml
new file mode 100644
index 00000000..48464272
--- /dev/null
+++ b/tests/xsl_attribute_as/test1_c.xml
@@ -0,0 +1,7 @@
+<info>
+  <val1>1</val1>
+  <val2>2</val2>
+  <val3>3</val3>
+  <val4>4</val4>
+  <val5>5</val5>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test1_d.xml b/tests/xsl_attribute_as/test1_d.xml
new file mode 100644
index 00000000..a6560d26
--- /dev/null
+++ b/tests/xsl_attribute_as/test1_d.xml
@@ -0,0 +1,7 @@
+<info>
+  <val>1</val>
+  <val>2</val>
+  <val1>3</val1>
+  <val>4</val>
+  <val>5</val>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test1_e.xml b/tests/xsl_attribute_as/test1_e.xml
new file mode 100644
index 00000000..218121cc
--- /dev/null
+++ b/tests/xsl_attribute_as/test1_e.xml
@@ -0,0 +1,7 @@
+<info>
+  <val attr1="1">1</val>
+  <val attr1="2">2</val>
+  <val attr1="3">3</val>
+  <val attr1="4">4</val>
+  <val attr1="test val">5</val>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_attribute_as/test4.xsl b/tests/xsl_attribute_as/test4.xsl
new file mode 100644
index 00000000..a6300477
--- /dev/null
+++ b/tests/xsl_attribute_as/test4.xsl
@@ -0,0 +1,51 @@
+<?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 the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->                 
+    
+    <xsl:output method="xml" indent="yes"/>
+        
+    <xsl:variable name="var1" select="/info/val" as="element()*"/>
+    <xsl:variable name="var2" select="/info/val" as="element(val)*"/>
+    <xsl:variable name="var3" select="/info/val" as="element(*)*"/>
+    
+    <xsl:template match="/">       
+       <result>
+          <one>
+	         <xsl:copy-of select="$var1"/>
+	      </one>
+	      <two>
+             <xsl:copy-of select="$var2"/>
+	      </two>
+	      <three>
+	         <xsl:copy-of select="$var3"/>
+	      </three>
+       </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/xsl_attribute_as/test5.xsl b/tests/xsl_attribute_as/test5.xsl
new file mode 100644
index 00000000..ff94dd18
--- /dev/null
+++ b/tests/xsl_attribute_as/test5.xsl
@@ -0,0 +1,41 @@
+<?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_c.xml -->               
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->                 
+    
+    <xsl:output method="xml" indent="yes"/>
+        
+    <xsl:variable name="var1" select="/info/*" as="element(*)*"/>
+    
+    <xsl:template match="/">       
+       <result>
+	      <xsl:copy-of select="$var1"/>
+       </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/xsl_attribute_as/test6.xsl b/tests/xsl_attribute_as/test6.xsl
new file mode 100644
index 00000000..cc170ba8
--- /dev/null
+++ b/tests/xsl_attribute_as/test6.xsl
@@ -0,0 +1,46 @@
+<?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_d.xml -->               
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+         
+         This stylesheet transformation fails, because one of the
+         XML instance element has name "val1", whereas the xsl:variable's
+         sequence type expression requires all XML sibling elements
+         /info/* to have name "val". 
+    -->                 
+    
+    <xsl:output method="xml" indent="yes"/>
+        
+    <xsl:variable name="var1" select="/info/*" as="element(val)*"/>
+    
+    <xsl:template match="/">       
+       <result>
+	      <xsl:copy-of select="$var1"/>
+       </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/xsl_attribute_as/test7.xsl b/tests/xsl_attribute_as/test7.xsl
new file mode 100644
index 00000000..4782d39e
--- /dev/null
+++ b/tests/xsl_attribute_as/test7.xsl
@@ -0,0 +1,41 @@
+<?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 the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->
+    
+    <xsl:output method="xml" indent="yes"/>
+        
+    <xsl:variable name="var1" select="/info//text()" as="text()*"/>
+    
+    <xsl:template match="/">       
+       <result>
+	      <xsl:value-of select="count($var1)"/>
+       </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/xsl_attribute_as/test8.xsl b/tests/xsl_attribute_as/test8.xsl
new file mode 100644
index 00000000..8fe4592f
--- /dev/null
+++ b/tests/xsl_attribute_as/test8.xsl
@@ -0,0 +1,43 @@
+<?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_b.xml -->               
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+        
+    <xsl:variable name="var1" select="for $x in /info/val return xs:string($x)" as="item()*"/>
+    
+    <xsl:template match="/">       
+       <result>
+	      <xsl:value-of select="$var1"/>
+       </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/xsl_attribute_as/test9.xsl b/tests/xsl_attribute_as/test9.xsl
new file mode 100644
index 00000000..0e1d016c
--- /dev/null
+++ b/tests/xsl_attribute_as/test9.xsl
@@ -0,0 +1,47 @@
+<?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_e.xml -->               
+    
+    <!-- An XSLT stylesheet test case, to test the sequence type
+         declaration attribute "as" on an xsl:variable instruction.
+    -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:template match="/info">       
+       <result>
+	      <xsl:for-each select="val">
+	         <xsl:variable name="attrVar" select="@*[1]" as="attribute(attr1)"/>
+	         <xsl:element name="valNew">
+	            <xsl:copy-of select="$attrVar"/>
+	            <xsl:value-of select="."/>
+	         </xsl:element>
+	      </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


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