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 2025/04/11 09:38:56 UTC

(xalan-java) branch xalan-j_xslt3.0_mvn updated: committing xalan-j xsl 3 implementation of xsl:try and xsl:catch instructions, along with few working related new test cases

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

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


The following commit(s) were added to refs/heads/xalan-j_xslt3.0_mvn by this push:
     new 0a66b9eb1 committing xalan-j xsl 3 implementation of xsl:try and xsl:catch instructions, along with few working related new test cases
0a66b9eb1 is described below

commit 0a66b9eb1fdcdcb2e28b9736cfab8694b7fcf015
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Fri Apr 11 15:08:37 2025 +0530

    committing xalan-j xsl 3 implementation of xsl:try and xsl:catch instructions, along with few working related new test cases
---
 README                                             |   8 +-
 .../org/apache/xalan/processor/XSLTSchema.java     |  71 +++-
 .../java/org/apache/xalan/templates/Constants.java |  22 +-
 .../apache/xalan/templates/ElemApplyTemplates.java |   6 +-
 .../java/org/apache/xalan/templates/ElemCatch.java | 262 +++++++++++++
 .../java/org/apache/xalan/templates/ElemTry.java   | 433 +++++++++++++++++++++
 .../org/apache/xalan/templates/TemplateList.java   |   6 +-
 src/main/java/org/apache/xpath/XPath.java          |  22 +-
 .../java/org/apache/xpath/operations/Variable.java |  43 +-
 .../apache/xalan/tests/main/Xsl3TestSuite2.java    |   3 +-
 .../apache/xalan/tests/xslt3/XslTryCatchTests.java | 112 ++++++
 src/test/resources/xsl_try_catch/gold/test1.out    |   6 +
 src/test/resources/xsl_try_catch/gold/test2.out    |   6 +
 src/test/resources/xsl_try_catch/gold/test3.out    |   1 +
 src/test/resources/xsl_try_catch/gold/test4.out    |   6 +
 src/test/resources/xsl_try_catch/gold/test5.out    |   6 +
 src/test/resources/xsl_try_catch/gold/test6.out    |   6 +
 src/test/resources/xsl_try_catch/test1.xsl         |  47 +++
 src/test/resources/xsl_try_catch/test2.xsl         |  46 +++
 src/test/resources/xsl_try_catch/test3.xsl         |  46 +++
 src/test/resources/xsl_try_catch/test4.xsl         |  47 +++
 src/test/resources/xsl_try_catch/test5.xsl         |  58 +++
 src/test/resources/xsl_try_catch/test6.xsl         |  57 +++
 23 files changed, 1275 insertions(+), 45 deletions(-)

diff --git a/README b/README
index 6ce443366..5b4d97595 100644
--- a/README
+++ b/README
@@ -17,7 +17,7 @@
 
 Copyright 1999-2025 The Apache Software Foundation
 
-Document last modified : 2025-04-09
+Document last modified : 2025-04-11
 
 Authors:
    Gary Gregory <gg...@apache.org>
@@ -59,16 +59,16 @@ This produces Maven build output with trailing information like following:
 [INFO]  T E S T S
 [INFO] -------------------------------------------------------
 [INFO] Running org.apache.xalan.tests.main.AllXsl3Tests
-[INFO] Tests run: 991, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 36.01 s - in org.apache.xalan.tests.main.AllXsl3Tests
+[INFO] Tests run: 997, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 69.188 s - in org.apache.xalan.tests.main.AllXsl3Tests
 [INFO]
 [INFO] Results:
 [INFO]
-[INFO] Tests run: 991, Failures: 0, Errors: 0, Skipped: 0
+[INFO] Tests run: 997, Failures: 0, Errors: 0, Skipped: 0
 [INFO]
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESS
 [INFO] ------------------------------------------------------------------------
-[INFO] Total time:  01:44 min
+[INFO] Total time:  02:34 min
 
 To run Xalan-J's XSL 3 processor for invoking an XSL stylesheet transformation, the jar file xalan-java-3.0.1.jar and other 
 jar files available within 'libs' folder need to be made available on Java run-time's classpath.   
diff --git a/src/main/java/org/apache/xalan/processor/XSLTSchema.java b/src/main/java/org/apache/xalan/processor/XSLTSchema.java
index 21d5b30f7..1fbedf878 100644
--- a/src/main/java/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/main/java/org/apache/xalan/processor/XSLTSchema.java
@@ -15,9 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id$
- */
 package org.apache.xalan.processor;
 
 import java.util.HashMap;
@@ -28,6 +25,7 @@ import org.apache.xalan.templates.ElemApplyImport;
 import org.apache.xalan.templates.ElemApplyTemplates;
 import org.apache.xalan.templates.ElemAttribute;
 import org.apache.xalan.templates.ElemCallTemplate;
+import org.apache.xalan.templates.ElemCatch;
 import org.apache.xalan.templates.ElemChoose;
 import org.apache.xalan.templates.ElemComment;
 import org.apache.xalan.templates.ElemCopy;
@@ -68,6 +66,7 @@ import org.apache.xalan.templates.ElemSourceDocument;
 import org.apache.xalan.templates.ElemTemplate;
 import org.apache.xalan.templates.ElemText;
 import org.apache.xalan.templates.ElemTextLiteral;
+import org.apache.xalan.templates.ElemTry;
 import org.apache.xalan.templates.ElemUnknown;
 import org.apache.xalan.templates.ElemValueOf;
 import org.apache.xalan.templates.ElemVariable;
@@ -229,6 +228,11 @@ public class XSLTSchema extends XSLTElementDef
                                               XSLTAttributeDef.T_QNAMES,
                                               false, false, XSLTAttributeDef.ERROR);
     
+    // Optional.
+    // xsl:catch      
+    XSLTAttributeDef errorsAttrOpt = new XSLTAttributeDef(null, "errors", XSLTAttributeDef.T_QNAMES,
+                                                                                    false, false, XSLTAttributeDef.ERROR);
+    
     // xsl:element, xsl:attribute                                           
     XSLTAttributeDef typeAttrOpt = new XSLTAttributeDef(null, "type",
             										XSLTAttributeDef.T_QNAME, false, false, XSLTAttributeDef.ERROR);
@@ -303,7 +307,8 @@ public class XSLTSchema extends XSLTElementDef
                                                   XSLTAttributeDef.T_EXPR, false, false, XSLTAttributeDef.ERROR);
 
     // Optional.                                          
-    // xsl:variable, xsl:value-of, xsl:param, xsl:with-param, xsl:attribute, xsl:break, xsl:on-completion, xsl:sequence                                       
+    // xsl:variable, xsl:value-of, xsl:param, xsl:with-param, xsl:attribute, xsl:break, 
+    // xsl:on-completion, xsl:sequence, xsl:try, xsl:catch                                       
     XSLTAttributeDef selectAttrOpt = new XSLTAttributeDef(null, "select",
                                        XSLTAttributeDef.T_EXPR, false, false, XSLTAttributeDef.ERROR);
     
@@ -326,13 +331,8 @@ public class XSLTSchema extends XSLTElementDef
     // Default: "."
     // xsl:sort                                        
     XSLTAttributeDef selectAttrDefDot = new XSLTAttributeDef(null, "select",
-                                          XSLTAttributeDef.T_EXPR, false,XSLTAttributeDef.ERROR, ".");
+                                          XSLTAttributeDef.T_EXPR, false,XSLTAttributeDef.ERROR, ".");    
     
-    // Optional.
-    // Default: "no"
-    // xsl:source-document
-    XSLTAttributeDef streamableAttr = new XSLTAttributeDef(null, "streamable",
-                                          XSLTAttributeDef.T_YESNO, false, false, XSLTAttributeDef.ERROR);
     // xsl:key                                      
     XSLTAttributeDef matchAttrRequired = new XSLTAttributeDef(null, "match",
                                            XSLTAttributeDef.T_PATTERN, true, false,XSLTAttributeDef.ERROR);
@@ -347,12 +347,23 @@ public class XSLTSchema extends XSLTElementDef
     XSLTAttributeDef modeAttr = new XSLTAttributeDef(null, "mode",
                                      XSLTAttributeDef.T_QNAME, false, false,XSLTAttributeDef.ERROR);
    
-    XSLTAttributeDef spaceAttr =
-      new XSLTAttributeDef(Constants.S_XMLNAMESPACEURI, "space", false, false, false, XSLTAttributeDef.WARNING,
-                           "default", Constants.ATTRVAL_STRIP, "preserve",
-                           Constants.ATTRVAL_PRESERVE);
-                           
-                         
+    XSLTAttributeDef spaceAttr = new XSLTAttributeDef(Constants.S_XMLNAMESPACEURI, "space", false, false, 
+    		                             false, XSLTAttributeDef.WARNING,
+                                         "default", Constants.ATTRVAL_STRIP, "preserve",
+                                         Constants.ATTRVAL_PRESERVE);
+    
+    // Optional.
+    // Default: "no"
+    // xsl:source-document
+    XSLTAttributeDef streamableAttr = new XSLTAttributeDef(null, "streamable",
+                                          XSLTAttributeDef.T_YESNO, false, false, XSLTAttributeDef.ERROR);
+    
+    // Optional.
+    // Default: "yes"
+    // xsl:try
+    XSLTAttributeDef rollbackOutputAttrOpt = new XSLTAttributeDef(null, "rollback-output",
+                                          					XSLTAttributeDef.T_YESNO, false, false, XSLTAttributeDef.ERROR);
+                                                    
     XSLTAttributeDef spaceAttrLiteral =
       new XSLTAttributeDef(Constants.S_XMLNAMESPACEURI, "space", 
                                           XSLTAttributeDef.T_URL, false, true,XSLTAttributeDef.ERROR);
@@ -471,13 +482,13 @@ public class XSLTSchema extends XSLTElementDef
                                                           XSLTAttributeDef.T_CDATA, false, false, 
                                                           XSLTAttributeDef.WARNING);
                            
-    XSLTElementDef[] templateElements = new XSLTElementDef[41];
-    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[42];
-    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[42];
+    XSLTElementDef[] templateElements = new XSLTElementDef[43];
+    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[44];
+    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[44];
     //exslt
-    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[42];
+    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[44];
     
-    XSLTElementDef[] charTemplateElements = new XSLTElementDef[23];
+    XSLTElementDef[] charTemplateElements = new XSLTElementDef[25];
     XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
                                      null /*alias */,
                                      templateElements /* elements */,
@@ -639,6 +650,20 @@ public class XSLTSchema extends XSLTElementDef
 								             new ProcessorTemplateElem(),
 								             ElemMergeAction.class /* class object */, true, false, true, 20, true);
     
+    XSLTElementDef xslTry = new XSLTElementDef(this,
+								             Constants.S_XSLNAMESPACEURL, "try",
+								             null /*alias */, templateElements,
+								             new XSLTAttributeDef[]{ selectAttrOpt, rollbackOutputAttrOpt, spaceAttr }, 
+								             new ProcessorTemplateElem(),
+								             ElemTry.class /* class object */, true, false, true, 20, true);
+    
+    XSLTElementDef xslCatch = new XSLTElementDef(this,
+								             Constants.S_XSLNAMESPACEURL, "catch",
+								             null /*alias */, templateElements,
+								             new XSLTAttributeDef[]{ selectAttrOpt, errorsAttrOpt, spaceAttr }, 
+								             new ProcessorTemplateElem(),
+								             ElemCatch.class /* class object */, true, false, true, 20, true);
+    
     XSLTElementDef xslAnalyzeString = new XSLTElementDef(this,
                                                 Constants.S_XSLNAMESPACEURL, "analyze-string",
                                                 null /*alias */, templateElements,
@@ -865,6 +890,8 @@ public class XSLTSchema extends XSLTElementDef
     templateElements[i++] = xslMergeSource;
     templateElements[i++] = xslMergeKey;
     templateElements[i++] = xslMergeAction;
+    templateElements[i++] = xslTry;
+    templateElements[i++] = xslCatch;
     templateElements[i++] = xslMatchingSubstring;
     templateElements[i++] = xslNonMatchingSubstring;
     templateElements[i++] = xslIterate;
@@ -919,6 +946,8 @@ public class XSLTSchema extends XSLTElementDef
     charTemplateElements[i++] = xslMergeSource;
     charTemplateElements[i++] = xslMergeKey;
     charTemplateElements[i++] = xslMergeAction;
+    charTemplateElements[i++] = xslTry;
+    charTemplateElements[i++] = xslCatch;
     charTemplateElements[i++] = xslValueOf;
     charTemplateElements[i++] = xslCopyOf;
     charTemplateElements[i++] = xslNumber;
diff --git a/src/main/java/org/apache/xalan/templates/Constants.java b/src/main/java/org/apache/xalan/templates/Constants.java
index 6d695559d..67e6efb1d 100644
--- a/src/main/java/org/apache/xalan/templates/Constants.java
+++ b/src/main/java/org/apache/xalan/templates/Constants.java
@@ -124,9 +124,13 @@ public class Constants extends org.apache.xml.utils.Constants
   
   ELEMNAME_FORK = 107,
   
-  ELEMNAME_RESULTDOCUMENT = 108;
+  ELEMNAME_RESULTDOCUMENT = 108,
   
-  // next available number : 109
+  ELEMNAME_TRY = 109,
+  
+  ELEMNAME_CATCH = 110;
+  
+  // next available number : 111
 
   /**
    * Literals for XSL element names. Note that there are more
@@ -175,6 +179,8 @@ public class Constants extends org.apache.xml.utils.Constants
       ELEMNAME_MERGE_SOURCE_STRING = "merge-source",
       ELEMNAME_MERGE_KEY_STRING = "merge-key",
       ELEMNAME_MERGE_ACTION_STRING = "merge-action",
+      ELEMNAME_TRY_STRING = "try",
+      ELEMNAME_CATCH_STRING = "catch",
       ELEMNAME_ANALYZESTRING_STRING = "analyze-string",
       ELEMNAME_MATCHINGSUBSTRING_STRING = "matching-substring",
       ELEMNAME_NONMATCHINGSUBSTRING_STRING = "non-matching-substring",
@@ -455,9 +461,15 @@ public class Constants extends org.apache.xml.utils.Constants
                              ATTRVAL_NAN = "NaN",
                              DEFAULT_DECIMAL_FORMAT = "#default";
 
-  public static final String XSL3_PATTERN_TABLE_DELIM = "#####";
+  public static final String XSL_PATTERN_TABLE_DELIM = "#####";
+  
+  /** XSLT 3.0 xsl:try and xsl:catch processing constants */
+  
+  public static final String XSL_ERROR_NAMESACE = "http://www.w3.org/2005/xqt-errors";
+  public static final String XSL_ERROR_CODE = "code";
+  public static final String XSL_ERROR_DESCRIPTION = "description";
+  public static final String XSL_ERROR_LINE_NUMBER = "line-number";
+  public static final String XSL_ERROR_COLUMN_NUMBER = "column-number";
   
-  /** temp dummy         */
-  public static final String ATTRNAME_XXXX = "XXXX";
   
 }
diff --git a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
index 90afd3e06..f59790d9e 100644
--- a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
+++ b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
@@ -733,10 +733,10 @@ public class ElemApplyTemplates extends ElemCallTemplate
 		  }
 		  
 		  String keyValueStr = (String)hashTableKeyObj;	  
-		  String[] strArray1 = keyValueStr.split(Constants.XSL3_PATTERN_TABLE_DELIM);
+		  String[] strArray1 = keyValueStr.split(Constants.XSL_PATTERN_TABLE_DELIM);
 		  if (keyValueStr.startsWith(".[") && (strArray1.length == 3)) {
 			  String xslTemplatePriorityStr = strArray1[2];			  
-			  String xpathStr = keyValueStr.substring(0, keyValueStr.indexOf(Constants.XSL3_PATTERN_TABLE_DELIM));
+			  String xpathStr = keyValueStr.substring(0, keyValueStr.indexOf(Constants.XSL_PATTERN_TABLE_DELIM));
 			  xpathStr = xpathStr.substring(2);
 			  xpathStr = xpathStr.substring(0, xpathStr.length() - 1);
 			  
@@ -797,7 +797,7 @@ public class ElemApplyTemplates extends ElemCallTemplate
 			  }
 			  
 			  String keyValueStr = (String)hashTableKeyObj;			  
-			  String[] strArray1 = keyValueStr.split(Constants.XSL3_PATTERN_TABLE_DELIM);
+			  String[] strArray1 = keyValueStr.split(Constants.XSL_PATTERN_TABLE_DELIM);
 			  if (".".equals(strArray1[0]) && (strArray1.length == 3)) {
 				 String xslTemplatePriorityStr = strArray1[2];
 				 TemplateDefnPriorityPair templateDefnPriorityPair = new TemplateDefnPriorityPair(keyValueStr, elemTemplate, 
diff --git a/src/main/java/org/apache/xalan/templates/ElemCatch.java b/src/main/java/org/apache/xalan/templates/ElemCatch.java
new file mode 100644
index 000000000..814bde879
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemCatch.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.templates;
+
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
+import org.xml.sax.SAXException;
+
+/**
+ * Implementation of the XSLT 3.0 xsl:catch instruction.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ *  
+ * @xsl.usage advanced
+ */
+public class ElemCatch extends ElemTemplateElement implements ExpressionOwner {
+
+	private static final long serialVersionUID = -1806774621639027295L;
+	
+	/**
+	 * The value of the "errors" attribute.
+	 */
+	private QName m_errorNames[] = null;
+
+	/**
+	 * Set the "errors" attribute.
+	 */
+	public void setErrors(Vector v)
+	{
+		int n = v.size();
+		m_errorNames = new QName[n];
+
+		for (int idx = 0; idx < n; idx++) {
+		   m_errorNames[idx] = (QName)v.elementAt(idx);
+		}
+	}
+	
+	/**
+	 * Get the value of "errors" attribute.
+	 */
+	public QName[] getErrors()
+	{
+	    return m_errorNames;
+	}
+	  
+	/**
+	 * The "select" expression.
+	 */
+	private XPath m_selectExpression = null;
+	
+	/**
+	 * Set the "select" attribute.
+	 *
+	 * @param xpath The XPath expression for the "select" attribute.
+	 */
+	public void setSelect(XPath xpath)
+	{
+		m_selectExpression = xpath;  
+	}
+
+	/**
+	 * Get the "select" attribute.
+	 *
+	 * @return The XPath expression for the "select" attribute.
+	 */
+	public XPath getSelect()
+	{
+		return m_selectExpression;
+	}
+	
+	/**
+	 * This class field is used during, XPath.fixupVariables(..) 
+	 * evaluation as performed within object of this class.  
+	 */    
+	private Vector m_vars;
+
+	/**
+	 * This class field is used during, XPath.fixupVariables(..) 
+	 * evaluation as performed within object of this class.  
+	 */
+	private int m_globals_size;
+
+	/**
+	 * The class constructor.
+	 */
+	public ElemCatch() {}
+	
+	/**
+	 * This function is called after everything else has been
+	 * recomposed, and allows the template to set remaining
+	 * values that may be based on some other property that
+	 * depends on recomposition.
+	 *
+	 * @param sroot
+	 *
+	 * @throws TransformerException
+	 */
+	public void compose(StylesheetRoot sroot) throws TransformerException
+	{
+		super.compose(sroot);
+		
+        java.util.Vector vnames = (sroot.getComposeState()).getVariableNames();
+	    
+	    m_vars = (Vector)(vnames.clone()); 
+	    m_globals_size = (sroot.getComposeState()).getGlobalsSize();
+
+	    if (m_selectExpression != null) {
+	        m_selectExpression.fixupVariables(vnames, m_globals_size);
+	    }
+	}
+
+	/**
+	 * This function is called after the template's children have been composed.
+	 */
+	public void endCompose(StylesheetRoot sroot) throws TransformerException
+	{     
+		super.endCompose(sroot);
+	}
+	
+	/**
+	 * Get an int constant identifying the type of element.
+	 * @see org.apache.xalan.templates.Constants
+	 *
+	 * @return The token ID for this element
+	 */
+	public int getXSLToken()
+	{
+		return Constants.ELEMNAME_CATCH;
+	}
+
+	/**
+	 * Return the node name.
+	 *
+	 * @return The element's name
+	 */
+	public String getNodeName()
+	{
+		return Constants.ELEMNAME_CATCH_STRING;
+	}
+	
+	/**
+	 * Run an XSL xsl:catch transformation.
+	 *
+	 * @param transformer non-null reference to the the current transform-time state.
+	 *
+	 * @throws TransformerException
+	 */
+	public void execute(TransformerImpl transformer) throws TransformerException
+	{
+        XPathContext xctxt = transformer.getXPathContext();
+	    
+	    SourceLocator srcLocator = xctxt.getSAXLocator();
+	    
+	    int contextNode = xctxt.getContextNode();
+	    
+	    ElemTemplateElement parentElem = this.getParentElem();
+	    if (!(parentElem instanceof ElemTry)) {
+	    	throw new TransformerException("XTSE3150 : An xsl:catch element can only occur as child of xsl:try element.", srcLocator);
+	    }
+	    
+	    if ((m_selectExpression != null) && (this.m_firstChild != null)) {
+	    	throw new TransformerException("XTSE3150 : An xsl:catch element can only have either 'select' attribute, or a contained "
+	    			                                                                                              + "sequence constructor.", srcLocator);
+		}
+	    
+	    if (m_selectExpression != null) {
+	    	if (m_vars != null) {
+    			m_selectExpression.fixupVariables(m_vars, m_globals_size);
+    		}
+
+    		m_selectExpression.setIsXslTryProcessing(true);
+    		XObject xpathEvalResult = m_selectExpression.execute(xctxt, contextNode, xctxt.getNamespaceContext());
+    		
+    		ResultSequence rSeq = new ResultSequence();
+			rSeq.add(xpathEvalResult);
+			SerializationHandler handler = transformer.getSerializationHandler(); 
+			try {
+				ElemCopyOf.copyOfActionOnResultSequence(rSeq, transformer, handler, xctxt, false);
+			} 
+			catch (TransformerException ex) {
+				throw new javax.xml.transform.TransformerException("XPTY0004 : An exception occured while serializing xsl:catch's evaluation "
+						                                                   + "to an XSL result tree, with following exception trace : " + 
+						                                                        ex.getMessage() + ".", srcLocator);	
+			} 
+			catch (SAXException ex) {
+				throw new javax.xml.transform.TransformerException("XPTY0004 : An exception occured while serializing xsl:catch's evaluation "
+                                                                           + "to an XSL result tree, with following exception trace : " + 
+                                                                               ex.getMessage() + ".", srcLocator);		
+			}
+	    }
+	    else {
+	    	for (ElemTemplateElement t = this.m_firstChild; t != null;
+	    															t = t.m_nextSibling) 
+	    	{
+	    		xctxt.setSAXLocator(t);
+	    		transformer.setCurrentElement(t);
+	    		t.execute(transformer);
+	    	}
+	    }
+	}
+	
+	/**
+	 * Add an XSL stylesheet child information.
+	 *
+	 * @param newChild Child to add to child list
+	 *
+	 * @return Child just added to child list
+	 */
+	public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+	{
+		return super.appendChild(newChild);
+	}
+
+	/**
+	 * Call the children visitors.
+	 * 
+	 * @param visitor The visitor whose appropriate method will be called.
+	 */
+	public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes)
+	{    
+		super.callChildVisitors(visitor, callAttributes);
+	}
+	
+	@Override
+	public Expression getExpression() {
+		// NO OP
+		return null;
+	}
+
+	@Override
+	public void setExpression(Expression exp) {
+		// NO OP
+	}
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/ElemTry.java b/src/main/java/org/apache/xalan/templates/ElemTry.java
new file mode 100644
index 000000000..2a5160392
--- /dev/null
+++ b/src/main/java/org/apache/xalan/templates/ElemTry.java
@@ -0,0 +1,433 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.templates;
+
+import java.util.Map;
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import xml.xpath31.processor.types.XSInteger;
+import xml.xpath31.processor.types.XSString;
+
+/**
+ * Implementation of the XSLT 3.0 xsl:try instruction.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class ElemTry extends ElemTemplateElement implements ExpressionOwner {
+
+	private static final long serialVersionUID = -3027484379104675428L;
+	
+	/**
+	 * The "select" expression.
+	 */
+	private XPath m_selectExpression = null;
+	
+	/**
+	 * This class field is used during, XPath.fixupVariables(..) 
+	 * evaluation as performed within object of this class.  
+	 */    
+	private Vector m_vars;
+
+	/**
+	 * This class field is used during, XPath.fixupVariables(..) 
+	 * evaluation as performed within object of this class.  
+	 */
+	private int m_globals_size;
+	
+	/**
+	 * Set the "select" attribute.
+	 *
+	 * @param xpath The XPath expression for the "select" attribute.
+	 */
+	public void setSelect(XPath xpath)
+	{
+		m_selectExpression = xpath;  
+	}
+
+	/**
+	 * Get the "select" attribute.
+	 *
+	 * @return The XPath expression for the "select" attribute.
+	 */
+	public XPath getSelect()
+	{
+		return m_selectExpression;
+	}
+	
+	/**
+	 * The "rollback-output" boolean value.
+	 * 
+	 * Default value is "yes".
+	 */
+	private boolean m_rollbackOutput = true;
+	
+	/**
+	 * Set the value of "rollback-output" attribute.
+	 *
+	 * @param rollbackOutput The boolean value for the "rollback-output" attribute.
+	 */
+	public void setRollbackOutput(boolean rollbackOutput)
+	{
+		m_rollbackOutput = rollbackOutput;   
+	}
+
+	/**
+	 * Get the value of "rollback-output" attribute.
+	 *
+	 * @return The boolean value for the "rollback-output" attribute.
+	 */
+	public boolean getRollbackOutput()
+	{
+		return m_rollbackOutput;
+	}
+	
+	/**
+	 * The class constructor.
+	 */
+	public ElemTry() {}
+	
+	/**
+	 * This function is called after everything else has been
+	 * recomposed, and allows the template to set remaining
+	 * values that may be based on some other property that
+	 * depends on recomposition.
+	 *
+	 * @param sroot
+	 *
+	 * @throws TransformerException
+	 */
+	public void compose(StylesheetRoot sroot) throws TransformerException
+	{
+		super.compose(sroot);
+		
+		java.util.Vector vnames = (sroot.getComposeState()).getVariableNames();
+	    
+	    m_vars = (Vector)(vnames.clone()); 
+	    m_globals_size = (sroot.getComposeState()).getGlobalsSize();
+
+	    if (m_selectExpression != null) {
+	        m_selectExpression.fixupVariables(vnames, m_globals_size);
+	    }
+	}
+
+	/**
+	 * This function is called after the template's children have been composed.
+	 */
+	public void endCompose(StylesheetRoot sroot) throws TransformerException
+	{     
+		super.endCompose(sroot);
+	}
+	
+	/**
+	 * Get an int constant identifying the type of element.
+	 * @see org.apache.xalan.templates.Constants
+	 *
+	 * @return The token ID for this element
+	 */
+	public int getXSLToken()
+	{
+		return Constants.ELEMNAME_TRY;
+	}
+
+	/**
+	 * Return the node name.
+	 *
+	 * @return The element's name
+	 */
+	public String getNodeName()
+	{
+		return Constants.ELEMNAME_TRY_STRING;
+	}
+	
+	/**
+	 * Run an XSL xsl:try transformation.
+	 *
+	 * @param transformer non-null reference to the the current transform-time state.
+	 *
+	 * @throws TransformerException
+	 */
+	public void execute(TransformerImpl transformer) throws TransformerException
+	{
+        XPathContext xctxt = transformer.getXPathContext();	    	    
+	    
+	    SourceLocator srcLocator = xctxt.getSAXLocator();
+	    
+	    int contextNode = xctxt.getContextNode();
+	    
+	    if (m_selectExpression != null) {
+	    	for (ElemTemplateElement t = this.m_firstChild; t != null;
+																	t = t.m_nextSibling) {
+	    		if (!(t instanceof ElemCatch)) {
+	    		   throw new TransformerException("XTSE3140 : An xsl:try element has 'select' attribute, but xsl:try "
+	    		   		                                                                 + "has a child element other than xsl:catch.", srcLocator);
+	    		}
+	    	}
+		}
+	    
+	    // Within xsl:try element, checking stylesheet node 
+	    // sibling occurrence validity. [1]
+	    Node node = getLastChildElem();
+	    if ((node == null) || !(node instanceof ElemCatch)) {
+	    	throw new TransformerException("XTSE3140 : An xsl:try element's last child element can only be a "
+	    			                                                                           + "xsl:catch element.", srcLocator);
+	    }
+
+	    while (node instanceof ElemCatch) {
+	       node = node.getPreviousSibling(); 
+	    }
+	    
+	    while (node != null) {
+	       node = node.getPreviousSibling();
+	       if ((node != null) && (node instanceof ElemCatch)) {
+	    	   throw new TransformerException("XTSE3140 : There cannot be a xsl:catch element as a preceding sibling of "
+	    	   		                                                                       + "a non xsl:catch element.", srcLocator);
+	       }
+	    }
+	    // end validation check [1]	    	    
+	    
+	    if (m_selectExpression != null) {
+	    	// An XSL processing specified by xsl:try element is
+	    	// been done by xsl:try element's 'select' attribute.
+	    	
+	    	try {	    			    		
+	    		if (m_vars != null) {
+	    			m_selectExpression.fixupVariables(m_vars, m_globals_size);
+	    		}
+
+	    		m_selectExpression.setIsXslTryProcessing(true);
+	    		XObject xpathEvalResult = m_selectExpression.execute(xctxt, contextNode, xctxt.getNamespaceContext());
+	    		
+	    		ResultSequence rSeq = new ResultSequence();
+    			rSeq.add(xpathEvalResult);
+    			SerializationHandler handler = transformer.getSerializationHandler(); 
+    			ElemCopyOf.copyOfActionOnResultSequence(rSeq, transformer, handler, xctxt, false);
+	    	}
+	    	catch (TransformerException ex) {
+				// This XSL dynamic exception may have a suitable xsl:catch element 
+	    		// handler. If such a xsl:catch element is available we'll evaluate 
+	    		// that xsl:catch element, otherwise XSL transformation processing 
+	    		// shall terminate with this exception.
+	    		
+	    		handleXslExceptionWithCatch(transformer, xctxt, ex);
+			}
+	    	catch (SAXException ex) {
+	    		throw new TransformerException(ex.getMessage(), srcLocator);
+	    	}
+	    }
+	    else {
+	    	// An XSL processing specified by xsl:try element is
+	    	// been done by xsl:try element's contained sequence
+	    	// constructor.
+	    	try {	    		
+	    		for (ElemTemplateElement t = this.m_firstChild; t != null;
+	    																t = t.m_nextSibling) 
+	    		{
+	    			if (!(t instanceof ElemCatch)) {
+	    				xctxt.setSAXLocator(t);
+	    				transformer.setCurrentElement(t);
+	    				t.execute(transformer);
+	    			}
+	    		}
+	    	}
+	    	catch (TransformerException ex) {
+	    		// This XSL dynamic exception may have a suitable xsl:catch element 
+	    		// handler. If such a xsl:catch element is available we'll evaluate 
+	    		// that xsl:catch element, otherwise XSL transformation processing 
+	    		// shall terminate with this exception.
+	    		
+				handleXslExceptionWithCatch(transformer, xctxt, ex);
+			}
+	    }
+	}
+	
+	/**
+	 * Add an XSL stylesheet child information.
+	 *
+	 * @param newChild Child to add to child list
+	 *
+	 * @return Child just added to child list
+	 */
+	public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+	{
+		return super.appendChild(newChild);
+	}
+
+	/**
+	 * Call the children visitors.
+	 * 
+	 * @param visitor The visitor whose appropriate method will be called.
+	 */
+	public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes)
+	{    
+		super.callChildVisitors(visitor, callAttributes);
+	}
+
+	@Override
+	public Expression getExpression() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void setExpression(Expression exp) {
+		// TODO Auto-generated method stub
+
+	}
+	
+	/**
+	 * During processing within xsl:try element when a run-time exception 
+	 * javax.xml.transform.TransformerException has occurred, handle the run-time
+	 * exception with an applicable xsl:catch element.
+	 * 
+	 * If a suitable xsl:catch element cannot be found to handle a run-time exception, 
+	 * an original exception is thrown to the client code as if XSL stylesheet
+	 * processing took place without using xsl:try instruction.
+	 * 
+	 * @param transformer					An XSL transformation TransformerImpl object instance
+	 * @param xctxt							An XPath context object
+	 * @param ex							An XSL run-time TransformerException object. 
+	 * @throws TransformerException
+	 */
+	private void handleXslExceptionWithCatch(TransformerImpl transformer, XPathContext xctxt, 
+																			    TransformerException ex) throws TransformerException {
+		
+		String errMesg = ex.getMessage();				
+		int colonIdx = errMesg.indexOf(':');
+		String errCodeStr = errMesg.substring(colonIdx + 1);
+		colonIdx = errCodeStr.indexOf(':');
+		if (colonIdx != -1) {
+		   errCodeStr = (errCodeStr.substring(0, colonIdx)).trim();
+		}
+		else {
+		   colonIdx = errMesg.indexOf(':');
+		   errCodeStr = (errMesg.substring(0, colonIdx)).trim();
+		}
+		
+		ElemCatch xslDesiredCatchElem = getXslCatchToHandleException(transformer, xctxt, errCodeStr, this);
+		
+		if (xslDesiredCatchElem != null) {
+			colonIdx = errMesg.indexOf(':');
+			String errMesg2 = errMesg.substring(colonIdx + 1);
+			colonIdx = errMesg2.indexOf(':');
+			errMesg2 = (errMesg2.substring(colonIdx + 1)).trim();
+			
+			// Set variables err:code, err:description, err:line-number, 
+			// err:column-number within XPath evaluation context.				
+			Map<QName, XObject> xpathVarMap = xctxt.getXPathVarMap();
+			QName varqName = new QName(Constants.XSL_ERROR_NAMESACE, Constants.XSL_ERROR_CODE);
+			xpathVarMap.put(varqName, new XSString(errCodeStr));
+			varqName = new QName(Constants.XSL_ERROR_NAMESACE, Constants.XSL_ERROR_DESCRIPTION);
+			xpathVarMap.put(varqName, new XSString(errMesg2));				
+			SourceLocator srcLocator2 = ex.getLocator();
+			int errLineNum = srcLocator2.getLineNumber();
+			int errColNum = srcLocator2.getColumnNumber();
+			varqName = new QName(Constants.XSL_ERROR_NAMESACE, Constants.XSL_ERROR_LINE_NUMBER);
+			xpathVarMap.put(varqName, new XSInteger(String.valueOf(errLineNum)));
+			varqName = new QName(Constants.XSL_ERROR_NAMESACE, Constants.XSL_ERROR_COLUMN_NUMBER);
+			xpathVarMap.put(varqName, new XSInteger(String.valueOf(errColNum)));
+			
+			xctxt.setSAXLocator(xslDesiredCatchElem);
+			transformer.setCurrentElement(xslDesiredCatchElem);
+			xslDesiredCatchElem.execute(transformer);
+		}
+		else {
+			throw ex;
+		}
+	}
+	
+	/**
+	 * Given an xsl:try element and a run-time error code string value, find the 
+	 * xsl:catch element that should perform an XSL transformation's error 
+	 * recovery.
+	 * 
+	 * @param transformer			An XSL transformation TransformerImpl object instance
+	 * @param xctxt					An XPath context object 
+	 * @param errCodeStr			Error code string value
+	 * @param elemTry				An xsl:try element object instance, for which xsl:catch element 
+	 *                              needs to be found for error recovery.
+	 * @return
+	 */
+	private ElemCatch getXslCatchToHandleException(TransformerImpl transformer, XPathContext xctxt, 
+			                                                                                  String errCodeStr, ElemTry elemTry) {
+		
+		ElemCatch xslDesiredCatchElem = null;
+		
+		for (ElemTemplateElement t = elemTry.m_firstChild; t != null;
+																t = t.m_nextSibling) 
+		{
+			if (t instanceof ElemCatch) {				
+				ElemCatch elemCatch = (ElemCatch)t;
+				QName[] qNameArr = elemCatch.getErrors();
+				if ((qNameArr == null) || ((qNameArr.length == 1) && "*".equals((qNameArr[0]).getLocalName()))) {
+					// This xsl:catch element doesn't have an attribute "errors", 
+					// or an attribute "errors" value is "*". That is, this xsl:catch element 
+					// is a suitable recovery handler for this exception.
+					xslDesiredCatchElem = elemCatch; 					
+				}
+				else {
+					for (int idx = 0; idx < qNameArr.length; idx++) {
+						QName xslCatchErrQName = qNameArr[idx];
+						if (errCodeStr.equals(xslCatchErrQName.getLocalName()) && 
+								(Constants.XSL_ERROR_NAMESACE).equals(xslCatchErrQName.getNamespace())) {
+							// An error code of an XPath dynamic error, matches 
+							// with this xsl:catch's error declaration.
+							xslDesiredCatchElem = elemCatch;
+						}
+					}
+				}
+			}
+		}
+
+		if (xslDesiredCatchElem == null) {
+			// None of xsl:catch elements within this xsl:try element
+			// were able to process the recovery of an XSL dynamic
+			// exception. We'll attempt to find an xsl:catch element if 
+			// available within this xsl:try's ancestor scope (i.e, any other 
+			// xsl:try ancestor element that can handle this exception).
+
+			ElemTemplateElement parentElem = elemTry.getParentElem();
+			while ((parentElem != null) && !(parentElem instanceof ElemTry)) {
+			   parentElem = parentElem.getParentElem();
+			}
+			
+			if ((parentElem != null) && (parentElem instanceof ElemTry)) {
+				xslDesiredCatchElem = getXslCatchToHandleException(transformer, xctxt, errCodeStr, (ElemTry)parentElem);
+			}
+		}
+		
+		return xslDesiredCatchElem;
+	}
+
+}
diff --git a/src/main/java/org/apache/xalan/templates/TemplateList.java b/src/main/java/org/apache/xalan/templates/TemplateList.java
index 50f5ce81b..918df5ae5 100644
--- a/src/main/java/org/apache/xalan/templates/TemplateList.java
+++ b/src/main/java/org/apache/xalan/templates/TemplateList.java
@@ -408,16 +408,16 @@ public class TemplateList implements java.io.Serializable
 	  }
 	  
 	  if (templateModeStr != null) {
-		  patternTableKeyStr = (patternTableKeyStr + Constants.XSL3_PATTERN_TABLE_DELIM + templateModeStr);  
+		  patternTableKeyStr = (patternTableKeyStr + Constants.XSL_PATTERN_TABLE_DELIM + templateModeStr);  
 	  }
 	  else {
-		  patternTableKeyStr = (patternTableKeyStr + Constants.XSL3_PATTERN_TABLE_DELIM + "mode_unspecified");		  
+		  patternTableKeyStr = (patternTableKeyStr + Constants.XSL_PATTERN_TABLE_DELIM + "mode_unspecified");		  
 	  }
 	  
 	  double templatePriority = template.getPriority();
 	  String templatePriorityStr = String.valueOf(templatePriority);
 	  
-	  patternTableKeyStr = (patternTableKeyStr + Constants.XSL3_PATTERN_TABLE_DELIM + templatePriorityStr);
+	  patternTableKeyStr = (patternTableKeyStr + Constants.XSL_PATTERN_TABLE_DELIM + templatePriorityStr);
 	  
 	  m_patternTable.put(patternTableKeyStr, association);
   }
diff --git a/src/main/java/org/apache/xpath/XPath.java b/src/main/java/org/apache/xpath/XPath.java
index 135b993a9..fda91e0f5 100644
--- a/src/main/java/org/apache/xpath/XPath.java
+++ b/src/main/java/org/apache/xpath/XPath.java
@@ -90,10 +90,18 @@ public class XPath implements Serializable, ExpressionOwner
   private String m_arrowop_remaining_xpath_expr_str = null;
   
   /**
-   * This class field with boolean true value denotes, that this XPath 
-   * expression corresponds to quantified expression's satisfies clause. 
+   * This class field with boolean value 'true' denotes, that 
+   * this XPath expression corresponds to quantified expression's 
+   * satisfies clause. 
    */
   private boolean m_is_quantified_expr;
+  
+  /**
+   * This class field with boolean value 'true' denotes, that 
+   * this XPath expression corresponds to xsl:try element 
+   * processing. 
+   */
+  private boolean m_is_xsltry_processing;
 
   /**
    * initial the function table
@@ -859,7 +867,7 @@ public class XPath implements Serializable, ExpressionOwner
 		  }
 		  te.setLocator(this.getLocator());
 		  ErrorListener el = xctxt.getErrorListener();
-		  if(null != el && !m_is_quantified_expr)
+		  if(null != el && !m_is_quantified_expr && !m_is_xsltry_processing)
 		  {
 			  el.error(te);
 		  }
@@ -904,4 +912,12 @@ public class XPath implements Serializable, ExpressionOwner
 	  return result;
   }
 
+  public void setIsXslTryProcessing(boolean bool) {
+	  m_is_xsltry_processing = bool;
+  }
+  
+  public boolean getIsXslTryProcessing() {
+	  return m_is_xsltry_processing; 
+  }
+
 }
diff --git a/src/main/java/org/apache/xpath/operations/Variable.java b/src/main/java/org/apache/xpath/operations/Variable.java
index 36e06a05c..b3fe4cf3f 100644
--- a/src/main/java/org/apache/xpath/operations/Variable.java
+++ b/src/main/java/org/apache/xpath/operations/Variable.java
@@ -25,9 +25,12 @@ import java.util.Map;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemCatch;
 import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
 import org.apache.xml.utils.QName;
 import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionNode;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
@@ -43,13 +46,17 @@ import org.apache.xpath.res.XPATHErrorResources;
  */
 public class Variable extends Expression implements PathComponent
 {
-    static final long serialVersionUID = -4334975375609297049L;
-  /** Tell if fixupVariables was called.
-   *  @serial   */
+  
+  static final long serialVersionUID = -4334975375609297049L;
+  
+  /**
+   * Tell if fixupVariables was called.
+   */
   private boolean m_fixUpWasCalled = false;
 
-  /** The qualified name of the variable.
-   *  @serial   */
+  /**
+   * The qualified name of the variable.
+   */
   protected QName m_qname;
   
   /**
@@ -135,6 +142,32 @@ public class Variable extends Expression implements PathComponent
 			  return;
 		  }
 	  }
+	  
+	  ExpressionNode exprOwnerNode = getExpressionOwner();
+	  boolean isVariableRefInXslCatch = false;
+	  if (exprOwnerNode instanceof ElemCatch) {
+		  isVariableRefInXslCatch = true; 
+	  }
+	  else {
+		  while (exprOwnerNode != null) {
+			  exprOwnerNode = exprOwnerNode.exprGetParent();
+			  if (exprOwnerNode instanceof ElemCatch) {
+				  isVariableRefInXslCatch = true;
+				  break;
+			  }
+		  }
+	  }
+	  
+	  if (isVariableRefInXslCatch) {
+		  java.lang.String varLocalName = m_qname.getLocalName();
+		  java.lang.String nsUri = m_qname.getNamespaceURI();
+		  if ((Constants.XSL_ERROR_NAMESACE).equals(nsUri)) {
+			 if (Constants.XSL_ERROR_CODE.equals(varLocalName) || Constants.XSL_ERROR_DESCRIPTION.equals(varLocalName) || 
+					 Constants.XSL_ERROR_LINE_NUMBER.equals(varLocalName) || Constants.XSL_ERROR_COLUMN_NUMBER.equals(varLocalName)) {
+				 return; 
+			 }
+		  }
+	  }
 
 	  if (m_xpathVarList.contains(m_qname)) {
 		  // This takes care of variable references within, XPath 3.1 expressions
diff --git a/src/test/java/org/apache/xalan/tests/main/Xsl3TestSuite2.java b/src/test/java/org/apache/xalan/tests/main/Xsl3TestSuite2.java
index ee3566641..707cb6617 100644
--- a/src/test/java/org/apache/xalan/tests/main/Xsl3TestSuite2.java
+++ b/src/test/java/org/apache/xalan/tests/main/Xsl3TestSuite2.java
@@ -80,6 +80,7 @@ import org.apache.xalan.tests.xslt3.XslSequenceInstTests;
 import org.apache.xalan.tests.xslt3.XslSourceDocumentTests;
 import org.apache.xalan.tests.xslt3.XslTemplateAttributeAsTests;
 import org.apache.xalan.tests.xslt3.XslTemplateTests;
+import org.apache.xalan.tests.xslt3.XslTryCatchTests;
 import org.apache.xalan.tests.xslt3.XslVariableAttributeAsTests;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
@@ -116,7 +117,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 XsGregorianTypeTests.class, XslMergeTests.class, XslSourceDocumentTests.class,
                 XslForkTests.class, XslResultDocumentTests.class, XPathIdivTests.class,
                 FnTransformTests.class, FnStartsWithEndsWithTests.class, FnContainsTests.class,
-                FnSubstringBeforeAndAfterTests.class })
+                FnSubstringBeforeAndAfterTests.class, XslTryCatchTests.class })
 public class Xsl3TestSuite2 {
 
 }
diff --git a/src/test/java/org/apache/xalan/tests/xslt3/XslTryCatchTests.java b/src/test/java/org/apache/xalan/tests/xslt3/XslTryCatchTests.java
new file mode 100644
index 000000000..5710256c2
--- /dev/null
+++ b/src/test/java/org/apache/xalan/tests/xslt3/XslTryCatchTests.java
@@ -0,0 +1,112 @@
+/*
+ * 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.tests.xslt3;
+
+import org.apache.xalan.tests.util.XSLConstants;
+import org.apache.xalan.tests.util.XSLTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSLT 3.0 stylesheet test cases to test, xsl:try and xsl:catch 
+ * instructions.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XslTryCatchTests extends XSLTransformTestsUtil {
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "xsl_try_catch/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "xsl_try_catch/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 xslTryCatchTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTryCatchTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTryCatchTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTryCatchTest4() {
+    	 String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl"; 
+         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+         
+         String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";
+         
+         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTryCatchTest5() {
+    	 String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl"; 
+         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+         
+         String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";
+         
+         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslTryCatchTest6() {
+    	 String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl"; 
+         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+         
+         String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";
+         
+         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/src/test/resources/xsl_try_catch/gold/test1.out b/src/test/resources/xsl_try_catch/gold/test1.out
new file mode 100644
index 000000000..ff5ebdc8e
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/gold/test1.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <error location="line : 18, column : 40">
+    <errCode>XPTY0004</errCode>
+    <reason>Number of arguments required for dynamic call to function is 2. Number of arguments provided 1.</reason>
+  </error>
+</result>
diff --git a/src/test/resources/xsl_try_catch/gold/test2.out b/src/test/resources/xsl_try_catch/gold/test2.out
new file mode 100644
index 000000000..cbf8faef7
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/gold/test2.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <error location="line : 17, column : 32">
+    <errCode>XPTY0004</errCode>
+    <reason>Number of arguments required for dynamic call to function is 2. Number of arguments provided 1.</reason>
+  </error>
+</result>
diff --git a/src/test/resources/xsl_try_catch/gold/test3.out b/src/test/resources/xsl_try_catch/gold/test3.out
new file mode 100644
index 000000000..040a9acda
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/gold/test3.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result>5</result>
diff --git a/src/test/resources/xsl_try_catch/gold/test4.out b/src/test/resources/xsl_try_catch/gold/test4.out
new file mode 100644
index 000000000..f6c8a59f6
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/gold/test4.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <error location="line : 18, column : 32">
+    <errCode>FOAR0001</errCode>
+    <reason>An integer division by zero error.</reason>
+  </error>
+</result>
diff --git a/src/test/resources/xsl_try_catch/gold/test5.out b/src/test/resources/xsl_try_catch/gold/test5.out
new file mode 100644
index 000000000..d28e33fad
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/gold/test5.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <error secondaryErrHandler="yes" location="line : 22, column : 33">
+    <errCode>FOAR0001</errCode>
+    <reason>An integer division by zero error.</reason>
+  </error>
+</result>
diff --git a/src/test/resources/xsl_try_catch/gold/test6.out b/src/test/resources/xsl_try_catch/gold/test6.out
new file mode 100644
index 000000000..ca9bfcaed
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/gold/test6.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <error location="line : 20, column : 32">
+    <errCode>FOAR0001</errCode>
+    <reason>An integer division by zero error.</reason>
+  </error>
+</result>
diff --git a/src/test/resources/xsl_try_catch/test1.xsl b/src/test/resources/xsl_try_catch/test1.xsl
new file mode 100644
index 000000000..3b63d2e04
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/test1.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"			    
+				xmlns:err="http://www.w3.org/2005/xqt-errors"
+			    exclude-result-prefixes="err"
+				version="3.0">
+
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSL stylesheet test case, to test xsl:try and xsl:catch 
+       instructions. -->
+  
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+		 <xsl:try>
+		   <xsl:variable name="func1" select="function($a, $b) { $a + $b }" as="function(*)"/>
+		   <xsl:value-of select="$func1(2)"/>
+		   <xsl:catch>
+		     <error location="line : {$err:line-number}, column : {$err:column-number}">
+			    <errCode><xsl:value-of select="$err:code"/></errCode>
+                <reason><xsl:value-of select="$err:description"/></reason>
+			 </error>
+		   </xsl:catch>
+		 </xsl:try>
+	 </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>
diff --git a/src/test/resources/xsl_try_catch/test2.xsl b/src/test/resources/xsl_try_catch/test2.xsl
new file mode 100644
index 000000000..5361c7f3a
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/test2.xsl
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"			    
+				xmlns:err="http://www.w3.org/2005/xqt-errors"
+			    exclude-result-prefixes="err"
+				version="3.0">
+				
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSL stylesheet test case, to test xsl:try and xsl:catch 
+       instructions. -->				
+
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+	     <xsl:variable name="func1" select="function($a, $b) { $a + $b }" as="function(*)"/>
+		 <xsl:try select="$func1(2)">		   
+		   <xsl:catch>
+		     <error location="line : {$err:line-number}, column : {$err:column-number}">
+			    <errCode><xsl:value-of select="$err:code"/></errCode>
+                <reason><xsl:value-of select="$err:description"/></reason>
+			 </error>
+		   </xsl:catch>
+		 </xsl:try>
+	 </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>
diff --git a/src/test/resources/xsl_try_catch/test3.xsl b/src/test/resources/xsl_try_catch/test3.xsl
new file mode 100644
index 000000000..a7df88a86
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/test3.xsl
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"			    
+				xmlns:err="http://www.w3.org/2005/xqt-errors"
+			    exclude-result-prefixes="err"
+				version="3.0">
+				
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSL stylesheet test case, to test xsl:try and xsl:catch 
+       instructions. -->				
+
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+	     <xsl:variable name="func1" select="function($a, $b) { $a + $b }" as="function(*)"/>
+		 <xsl:try select="$func1(2, 3)">		   
+		   <xsl:catch>
+		     <error location="line : {$err:line-number}, column : {$err:column-number}">
+			    <errCode><xsl:value-of select="$err:code"/></errCode>
+                <reason><xsl:value-of select="$err:description"/></reason>
+			 </error>
+		   </xsl:catch>
+		 </xsl:try>
+	 </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>
diff --git a/src/test/resources/xsl_try_catch/test4.xsl b/src/test/resources/xsl_try_catch/test4.xsl
new file mode 100644
index 000000000..ece15bc95
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/test4.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"			    
+				xmlns:err="http://www.w3.org/2005/xqt-errors"
+			    exclude-result-prefixes="err"
+				version="3.0">
+				
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSL stylesheet test case, to test xsl:try and xsl:catch 
+       instructions. -->				
+
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+         <xsl:variable name="x" select="5"/>
+         <xsl:variable name="y" select="0"/>		 
+		 <xsl:try select="$x div $y">
+		   <xsl:catch>
+		     <error location="line : {$err:line-number}, column : {$err:column-number}">
+			    <errCode><xsl:value-of select="$err:code"/></errCode>
+                <reason><xsl:value-of select="$err:description"/></reason>
+			 </error>
+		   </xsl:catch>
+		 </xsl:try>
+	 </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>
diff --git a/src/test/resources/xsl_try_catch/test5.xsl b/src/test/resources/xsl_try_catch/test5.xsl
new file mode 100644
index 000000000..fec54c047
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/test5.xsl
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"			    
+				xmlns:err="http://www.w3.org/2005/xqt-errors"
+			    exclude-result-prefixes="err"
+				version="3.0">
+				
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSL stylesheet test case, to test xsl:try and xsl:catch 
+       instructions. This stylesheet tests using xsl:catch element,
+       within xsl:try element that is above the xsl:try element 
+       which caused an XSL stylesheet run-time error.        
+  -->				
+
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+         <xsl:variable name="x" select="5"/>
+         <xsl:variable name="y" select="0"/>
+         <xsl:try>
+			 <xsl:try select="$x div $y">		 
+			   <xsl:catch errors="err:XTTE1540">
+				 <error location="line : {$err:line-number}, column : {$err:column-number}">
+					<errCode><xsl:value-of select="$err:code"/></errCode>
+					<reason><xsl:value-of select="$err:description"/></reason>
+				 </error>
+			   </xsl:catch>
+			 </xsl:try>
+             <xsl:catch errors="*">
+                <error location="line : {$err:line-number}, column : {$err:column-number}" secondaryErrHandler="yes">
+				   <errCode><xsl:value-of select="$err:code"/></errCode>
+				   <reason><xsl:value-of select="$err:description"/></reason>
+				</error>
+             </xsl:catch>			 
+		 </xsl:try>
+	 </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>
diff --git a/src/test/resources/xsl_try_catch/test6.xsl b/src/test/resources/xsl_try_catch/test6.xsl
new file mode 100644
index 000000000..f0b6987d1
--- /dev/null
+++ b/src/test/resources/xsl_try_catch/test6.xsl
@@ -0,0 +1,57 @@
+<?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"			    
+				xmlns:err="http://www.w3.org/2005/xqt-errors"
+				xmlns:fn0="http://fn0"
+			    exclude-result-prefixes="xs err fn0"
+				version="3.0">
+				
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSL stylesheet test case, to test xsl:try and xsl:catch 
+       instructions. -->				
+
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+         <xsl:variable name="x" select="5"/>
+         <xsl:variable name="y" select="0"/>		 
+		 <xsl:try select="$x div $y">
+		   <xsl:catch errors="*" select="fn0:xslCatchProcessing(string($err:code), $err:description, $err:line-number, $err:column-number)"/>
+		 </xsl:try>
+	 </result>
+  </xsl:template>
+  
+  <!-- An XSL stylesheet function definition, to do processing for xsl:catch 
+       element. -->
+  <xsl:function name="fn0:xslCatchProcessing" as="element(error)">    
+	<xsl:param name="errCode" as="xs:string"/>
+	<xsl:param name="errDesc" as="xs:string"/>
+	<xsl:param name="lineNum" as="xs:integer"/>
+	<xsl:param name="columnNum" as="xs:integer"/>
+	<error location="line : {$lineNum}, column : {$columnNum}">
+	  <errCode><xsl:value-of select="$errCode"/></errCode>
+      <reason><xsl:value-of select="$errDesc"/></reason>
+    </error>
+  </xsl:function>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>


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