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