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 2024/05/31 10:24:55 UTC
(xalan-java) branch xalan-j_xslt3.0 updated: xalanj xsl3 branch changes : committing implementation of xpath3.1 array functions insert-before, head, tail, reverse. refactoring of few codebase files. adding various new working relevant test cases as well.
This is an automated email from the ASF dual-hosted git repository.
mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git
The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
new e9029d32 xalanj xsl3 branch changes : committing implementation of xpath3.1 array functions insert-before, head, tail, reverse. refactoring of few codebase files. adding various new working relevant test cases as well.
e9029d32 is described below
commit e9029d32935adec84275ff600e806928bdc2ad00
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Fri May 31 15:54:42 2024 +0530
xalanj xsl3 branch changes : committing implementation of xpath3.1 array functions insert-before, head, tail, reverse. refactoring of few codebase files. adding various new working relevant test cases as well.
---
src/org/apache/xpath/compiler/FunctionTable.java | 12 ++
src/org/apache/xpath/compiler/XPathParserImpl.java | 183 ++++++++++++++-------
.../xpath/composite/SequenceTypeSupport.java | 22 ++-
src/org/apache/xpath/functions/FuncForEach.java | 8 +-
.../xpath/functions/array/FuncArrayHead.java | 74 +++++++++
.../functions/array/FuncArrayInsertBefore.java | 136 +++++++++++++++
.../xpath/functions/array/FuncArrayReverse.java | 76 +++++++++
.../xpath/functions/array/FuncArrayTail.java | 82 +++++++++
.../xalan/xpath3/InlineFunctionItemExprTests.java | 3 +-
tests/org/apache/xalan/xpath3/XPathArrayTests.java | 40 +++++
tests/org/apache/xalan/xpath3/XPathMapTests.java | 40 +++++
tests/xpath_array/gold/test10.out | 4 +
tests/xpath_array/gold/test11.out | 4 +
tests/xpath_array/gold/test12.out | 3 +
tests/xpath_array/gold/test9.out | 5 +
tests/xpath_array/test10.xsl | 55 +++++++
tests/xpath_array/test11.xsl | 51 ++++++
tests/xpath_array/test12.xsl | 43 +++++
tests/xpath_array/test9.xsl | 54 ++++++
tests/xpath_maps/gold/test17.out | 5 +
tests/xpath_maps/gold/test18.out | 5 +
tests/xpath_maps/gold/test19.out | 5 +
tests/xpath_maps/gold/test20.out | 5 +
tests/xpath_maps/test15.xsl | 6 +-
tests/xpath_maps/test16.xsl | 6 +-
tests/xpath_maps/{test16.xsl => test17.xsl} | 36 +---
tests/xpath_maps/{test15.xsl => test18.xsl} | 36 +---
tests/xpath_maps/{test15.xsl => test19.xsl} | 14 +-
tests/xpath_maps/{test16.xsl => test20.xsl} | 14 +-
29 files changed, 888 insertions(+), 139 deletions(-)
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 0161cb64..5bc394f8 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -805,6 +805,10 @@ public class FunctionTable
m_functions[FUNC_ARRAY_APPEND] = org.apache.xpath.functions.array.FuncArrayAppend.class;
m_functions[FUNC_ARRAY_SUBARRAY] = org.apache.xpath.functions.array.FuncSubarray.class;
m_functions[FUNC_ARRAY_REMOVE] = org.apache.xpath.functions.array.FuncArrayRemove.class;
+ m_functions[FUNC_ARRAY_INSERT_BEFORE] = org.apache.xpath.functions.array.FuncArrayInsertBefore.class;
+ m_functions[FUNC_ARRAY_HEAD] = org.apache.xpath.functions.array.FuncArrayHead.class;
+ m_functions[FUNC_ARRAY_TAIL] = org.apache.xpath.functions.array.FuncArrayTail.class;
+ m_functions[FUNC_ARRAY_REVERSE] = org.apache.xpath.functions.array.FuncArrayReverse.class;
// XPath 3.1 built-in functions configurations for the map
// functions namespace http://www.w3.org/2005/xpath-functions/map
@@ -1108,6 +1112,14 @@ public class FunctionTable
new Integer(FunctionTable.FUNC_ARRAY_SUBARRAY));
m_functionID.put(Keywords.FUNC_ARRAY_REMOVE,
new Integer(FunctionTable.FUNC_ARRAY_REMOVE));
+ m_functionID.put(Keywords.FUNC_ARRAY_INSERT_BEFORE,
+ new Integer(FunctionTable.FUNC_ARRAY_INSERT_BEFORE));
+ m_functionID.put(Keywords.FUNC_ARRAY_HEAD,
+ new Integer(FunctionTable.FUNC_ARRAY_HEAD));
+ m_functionID.put(Keywords.FUNC_ARRAY_TAIL,
+ new Integer(FunctionTable.FUNC_ARRAY_TAIL));
+ m_functionID.put(Keywords.FUNC_ARRAY_REVERSE,
+ new Integer(FunctionTable.FUNC_ARRAY_REVERSE));
m_functionID.put(Keywords.FUNC_NAME_STRING,
new Integer(FunctionTable.FUNC_NAME));
diff --git a/src/org/apache/xpath/compiler/XPathParserImpl.java b/src/org/apache/xpath/compiler/XPathParserImpl.java
index 427f9b93..74575656 100644
--- a/src/org/apache/xpath/compiler/XPathParserImpl.java
+++ b/src/org/apache/xpath/compiler/XPathParserImpl.java
@@ -59,8 +59,7 @@ import org.apache.xpath.objects.XString;
import org.apache.xpath.res.XPATHErrorResources;
/**
- * This class implements an XPath language parser, using
- * an XPath input expression string.
+ * Tokenizes and parses XPath expressions.
*
* Ref: https://www.w3.org/TR/xpath-31/
* (please also refer to section 'A XPath 3.1 Grammar', within
@@ -72,9 +71,9 @@ import org.apache.xpath.res.XPATHErrorResources;
* Henry Zongaro, Christine Li
*
* @author Mukul Gandhi
- * (XPath 3 language changes, to this class)
+ * (XPath 3 specific changes, to this class)
*
- * @xsl.usage internal
+ * @xsl.usage general
*/
public class XPathParserImpl
{
@@ -1045,62 +1044,17 @@ public class XPathParserImpl
// a FilterExpr.
id = Keywords.lookupNodeTest(key);
if (id == null) {
- if ((FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI).equals(nsUri)) {
- if ("contains".equals(key)) {
- id = FunctionTable.FUNC_CONTAINS;
- }
- else if ("remove".equals(key)) {
- id = FunctionTable.FUNC_REMOVE;
- }
- else {
- id = m_functionTable.getFunctionID(key);
- }
+ if ((FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI).equals(nsUri)) {
+ id = getFunctionTokenForXPathBuiltinFuncs(key);
}
- else if ((FunctionTable.XPATH_BUILT_IN_MAP_FUNCS_NS_URI).equals(nsUri)) {
- if ("size".equals(key)) {
- id = FunctionTable.FUNC_MAP_SIZE;
- }
- else if ("get".equals(key)) {
- id = FunctionTable.FUNC_MAP_GET;
- }
- else if ("put".equals(key)) {
- id = FunctionTable.FUNC_MAP_PUT;
- }
- else if ("contains".equals(key)) {
- id = FunctionTable.FUNC_MAP_CONTAINS;
- }
- else if ("keys".equals(key)) {
- id = FunctionTable.FUNC_MAP_KEYS;
- }
- else if ("entry".equals(key)) {
- id = FunctionTable.FUNC_MAP_ENTRY;
- }
- else if ("for-each".equals(key)) {
- id = FunctionTable.FUNC_MAP_FOREACH;
- }
+ else if ((FunctionTable.XPATH_BUILT_IN_MAP_FUNCS_NS_URI).equals(nsUri)) {
+ id = getFunctionTokenForXPathBuiltinMapFuncs(key);
}
- else if ((FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI).equals(nsUri)) {
- if ("size".equals(key)) {
- id = FunctionTable.FUNC_ARRAY_SIZE;
- }
- else if ("get".equals(key)) {
- id = FunctionTable.FUNC_ARRAY_GET;
- }
- else if ("put".equals(key)) {
- id = FunctionTable.FUNC_ARRAY_PUT;
- }
- else if ("append".equals(key)) {
- id = FunctionTable.FUNC_ARRAY_APPEND;
- }
- else if ("subarray".equals(key)) {
- id = FunctionTable.FUNC_ARRAY_SUBARRAY;
- }
- else if ("remove".equals(key)) {
- id = FunctionTable.FUNC_ARRAY_REMOVE;
- }
+ else if ((FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI).equals(nsUri)) {
+ id = getFunctionTokenForXPathBuiltinArrayFuncs(key);
}
else {
- id = m_functionTable.getFunctionID(key);
+ id = m_functionTable.getFunctionID(key);
}
}
tok = ((Integer) id).intValue();
@@ -1117,6 +1071,123 @@ public class XPathParserImpl
return tok;
}
+ /**
+ * Get function token, for XPath built-in functions from namespace
+ * http://www.w3.org/2005/xpath-functions.
+ */
+ private Object getFunctionTokenForXPathBuiltinFuncs(String key) {
+ Object id = null;
+
+ switch (key) {
+ case "contains":
+ id = FunctionTable.FUNC_CONTAINS;
+ break;
+ case "remove":
+ id = FunctionTable.FUNC_REMOVE;
+ break;
+ case "for-each":
+ id = FunctionTable.FUNC_FOR_EACH;
+ break;
+ case "insert-before":
+ id = FunctionTable.FUNC_INSERT_BEFORE;
+ break;
+ case "head":
+ id = FunctionTable.FUNC_HEAD;
+ break;
+ case "tail":
+ id = FunctionTable.FUNC_TAIL;
+ break;
+ case "reverse":
+ id = FunctionTable.FUNC_REVERSE;
+ break;
+ default:
+ id = m_functionTable.getFunctionID(key);
+ }
+
+ return id;
+ }
+
+ /**
+ * Get function token, for XPath built-in map functions from namespace
+ * http://www.w3.org/2005/xpath-functions/map.
+ */
+ private Object getFunctionTokenForXPathBuiltinMapFuncs(String key) {
+ Object id = null;
+
+ switch (key) {
+ case "size":
+ id = FunctionTable.FUNC_MAP_SIZE;
+ break;
+ case "get":
+ id = FunctionTable.FUNC_MAP_GET;
+ break;
+ case "put":
+ id = FunctionTable.FUNC_MAP_PUT;
+ break;
+ case "contains":
+ id = FunctionTable.FUNC_MAP_CONTAINS;
+ break;
+ case "keys":
+ id = FunctionTable.FUNC_MAP_KEYS;
+ break;
+ case "entry":
+ id = FunctionTable.FUNC_MAP_ENTRY;
+ break;
+ case "for-each":
+ id = FunctionTable.FUNC_MAP_FOREACH;
+ break;
+ default:
+ // NO OP
+ }
+
+ return id;
+ }
+
+ /**
+ * Get function token, for XPath built-in array functions from namespace
+ * http://www.w3.org/2005/xpath-functions/array.
+ */
+ private Object getFunctionTokenForXPathBuiltinArrayFuncs(String key) {
+ Object id = null;
+
+ switch (key) {
+ case "size":
+ id = FunctionTable.FUNC_ARRAY_SIZE;
+ break;
+ case "get":
+ id = FunctionTable.FUNC_ARRAY_GET;
+ break;
+ case "put":
+ id = FunctionTable.FUNC_ARRAY_PUT;
+ break;
+ case "append":
+ id = FunctionTable.FUNC_ARRAY_APPEND;
+ break;
+ case "subarray":
+ id = FunctionTable.FUNC_ARRAY_SUBARRAY;
+ break;
+ case "remove":
+ id = FunctionTable.FUNC_ARRAY_REMOVE;
+ break;
+ case "insert-before":
+ id = FunctionTable.FUNC_ARRAY_INSERT_BEFORE;
+ break;
+ case "head":
+ id = FunctionTable.FUNC_ARRAY_HEAD;
+ break;
+ case "tail":
+ id = FunctionTable.FUNC_ARRAY_TAIL;
+ break;
+ case "reverse":
+ id = FunctionTable.FUNC_ARRAY_REVERSE;
+ break;
+ default:
+ // NO OP
+ }
+
+ return id;
+ }
+
/**
* Insert room for operation. This will NOT set
* the length value of the operation, but will update
diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
index 6ece7c06..daf48318 100644
--- a/src/org/apache/xpath/composite/SequenceTypeSupport.java
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -25,6 +25,7 @@ import java.util.Set;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
+import org.apache.xalan.templates.XMLNSDecl;
import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
@@ -165,7 +166,7 @@ public class SequenceTypeSupport {
public static String INLINE_FUNCTION_PARAM_TYPECHECK_COUNT_ERROR = "INLINE_FUNCTION_PARAM_TYPECHECK_COUNT_ERROR";
- private static List fPrefixTable;
+ private static List<XMLNSDecl> fPrefixTable;
/**
* This method converts/casts an XPath 3.1 xdm source value represented by an
@@ -268,6 +269,25 @@ public class SequenceTypeSupport {
int itemTypeOccurenceIndicator = seqExpectedTypeData.getItemTypeOccurrenceIndicator();
SequenceTypeKindTest sequenceTypeKindTest = seqExpectedTypeData.getSequenceTypeKindTest();
+ if ((srcValue != null) && (sequenceTypeKindTest != null)) {
+ if (sequenceTypeKindTest.getKindVal() == ITEM_KIND) {
+ if (srcValue instanceof XPathArray) {
+ XPathArray xpathArr = (XPathArray)srcValue;
+ if (itemTypeOccurenceIndicator == OccurenceIndicator.ZERO_OR_MANY) {
+ result = xpathArr;
+ }
+ else if ((itemTypeOccurenceIndicator == OccurenceIndicator.ONE_OR_MANY) && (xpathArr.size() > 0)) {
+ result = xpathArr;
+ }
+ else if ((itemTypeOccurenceIndicator == OccurenceIndicator.ZERO_OR_ONE) && (xpathArr.size() <= 1)) {
+ result = xpathArr;
+ }
+
+ return result;
+ }
+ }
+ }
+
if (srcValue instanceof XString) {
String srcStrVal = ((XString)srcValue).str();
diff --git a/src/org/apache/xpath/functions/FuncForEach.java b/src/org/apache/xpath/functions/FuncForEach.java
index 163b367e..6ec5a4c8 100644
--- a/src/org/apache/xpath/functions/FuncForEach.java
+++ b/src/org/apache/xpath/functions/FuncForEach.java
@@ -111,7 +111,7 @@ public class FuncForEach extends Function2Args {
if (arg1 instanceof InlineFunction) {
InlineFunction inlineFuncArg = (InlineFunction)arg1;
- validateInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
+ verifyInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
resultSeq = evaluateFnForEach(xctxt, arg0XsObject, arg0DtmIterator, inlineFuncArg);
}
else if (arg1 instanceof Variable) {
@@ -122,7 +122,7 @@ public class FuncForEach extends Function2Args {
XObject arg1VarValue = arg1.execute(xctxt);
if (arg1VarValue instanceof InlineFunction) {
InlineFunction inlineFuncArg = (InlineFunction)arg1VarValue;
- validateInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
+ verifyInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
resultSeq = evaluateFnForEach(xctxt, arg0XsObject, arg0DtmIterator, inlineFuncArg);
}
else {
@@ -172,9 +172,9 @@ public class FuncForEach extends Function2Args {
}
/*
- * Validate the, number of function parameters, that the inline function is allowed to have for fn:for-each.
+ * Verify the, number of function parameters, that the inline function is allowed to have for fn:for-each.
*/
- private void validateInlineFunctionParamCardinality(InlineFunction inlineFuncArg, SourceLocator srcLocator) throws
+ private void verifyInlineFunctionParamCardinality(InlineFunction inlineFuncArg, SourceLocator srcLocator) throws
javax.xml.transform.TransformerException {
List<InlineFunctionParameter> funcParamList = inlineFuncArg.getFuncParamList();
if (funcParamList.size() != 1) {
diff --git a/src/org/apache/xpath/functions/array/FuncArrayHead.java b/src/org/apache/xpath/functions/array/FuncArrayHead.java
new file mode 100644
index 00000000..9b61005b
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayHead.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.functions.array;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FunctionOneArg;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+/**
+ * Implementation of the array:head function.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FuncArrayHead extends FunctionOneArg {
+
+ private static final long serialVersionUID = -3207085299844796544L;
+
+ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+ {
+ XObject result = null;
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ Expression arg0 = getArg0();
+
+ XObject xObject = null;
+
+ if (arg0 instanceof Variable) {
+ xObject = ((Variable)arg0).execute(xctxt);
+ }
+ else {
+ xObject = arg0.execute(xctxt);
+ }
+
+ if (xObject instanceof XPathArray) {
+ XPathArray xpathArr = (XPathArray)xObject;
+ if (xpathArr.size() > 0) {
+ result = xpathArr.get(0);
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : An array:head function call's argument "
+ + "cannot be an empty array.", srcLocator);
+ }
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 1st argument of function array:head, "
+ + "needs to be an array.", srcLocator);
+ }
+
+ return result;
+ }
+
+}
diff --git a/src/org/apache/xpath/functions/array/FuncArrayInsertBefore.java b/src/org/apache/xpath/functions/array/FuncArrayInsertBefore.java
new file mode 100644
index 00000000..f734a0fd
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayInsertBefore.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.functions.array;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.Function3Args;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+import xml.xpath31.processor.types.XSNumericType;
+
+/**
+ * Implementation of the array:insert-before function.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FuncArrayInsertBefore extends Function3Args {
+
+ private static final long serialVersionUID = -6993811075719408978L;
+
+ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+ {
+ XObject result = null;
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ Expression arg0Expr = getArg0();
+ Expression arg1Expr = getArg1();
+ Expression arg2Expr = getArg2();
+
+ XPathArray arg0XPathArr = null;
+
+ List<XObject> nativeArr = null;
+ if (arg0Expr instanceof Variable) {
+ XObject xObject = ((Variable)arg0Expr).execute(xctxt);
+ if (xObject instanceof XPathArray) {
+ arg0XPathArr = (XPathArray)xObject;
+ nativeArr = arg0XPathArr.getNativeArray();
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FORG0006 : The 1st argument of array:insert-before function call, "
+ + "needs to be an array", srcLocator);
+ }
+ }
+ else {
+ XObject xObject = arg0Expr.execute(xctxt);
+ if (xObject instanceof XPathArray) {
+ arg0XPathArr = (XPathArray)xObject;
+ nativeArr = arg0XPathArr.getNativeArray();
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FORG0006 : The 1st argument of array:insert-before function call, "
+ + "needs to be an array", srcLocator);
+ }
+ }
+
+ XObject arg1XObj = null;
+ if (arg1Expr instanceof Variable) {
+ arg1XObj = ((Variable)arg1Expr).execute(xctxt);
+ if (!((arg1XObj instanceof XSNumericType) || (arg1XObj instanceof XNumber))) {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function "
+ + "call, needs to be an xs:integer value", srcLocator);
+ }
+ }
+ else {
+ arg1XObj = arg1Expr.execute(xctxt);
+ if (!((arg1XObj instanceof XSNumericType) || (arg1XObj instanceof XNumber))) {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function "
+ + "call, needs to be an xs:integer value", srcLocator);
+ }
+ }
+
+ XObject arg2XObj = null;
+ if (arg2Expr instanceof Variable) {
+ arg2XObj = ((Variable)arg2Expr).execute(xctxt);
+ }
+ else {
+ arg2XObj = arg2Expr.execute(xctxt);
+ }
+
+ int arg1Int;
+ try {
+ arg1Int = Integer.valueOf(XslTransformEvaluationHelper.getStrVal(arg1XObj));
+ int inpArrSize = nativeArr.size();
+ if ((arg1Int < 1) || (arg1Int > (inpArrSize + 1))) {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function all, needs to be "
+ + "an xs:integer value in the range 1 to (array:size($array) + 1) inclusive", srcLocator);
+ }
+ }
+ catch (NumberFormatException ex) {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function "
+ + "call, needs to be an xs:integer value", srcLocator);
+ }
+
+ List<XObject> resultL = nativeArr.subList(0, arg1Int - 1);
+ List<XObject> resultR = nativeArr.subList(arg1Int - 1, nativeArr.size());
+
+ List<XObject> resultNativeArr = new ArrayList<XObject>();
+ resultNativeArr.addAll(resultL);
+ resultNativeArr.add(arg2XObj);
+ resultNativeArr.addAll(resultR);
+
+ XPathArray resultArr = new XPathArray();
+ resultArr.setNativeArray(resultNativeArr);
+
+ result = resultArr;
+
+ return result;
+ }
+
+}
diff --git a/src/org/apache/xpath/functions/array/FuncArrayReverse.java b/src/org/apache/xpath/functions/array/FuncArrayReverse.java
new file mode 100644
index 00000000..ddb75baf
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayReverse.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.functions.array;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FunctionOneArg;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+import xml.xpath31.processor.types.XSInteger;
+
+/**
+ * Implementation of the array:reverse function.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FuncArrayReverse extends FunctionOneArg {
+
+ private static final long serialVersionUID = 8786348949335466009L;
+
+ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+ {
+ XObject result = null;
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ Expression arg0 = getArg0();
+
+ XObject xObject = null;
+
+ if (arg0 instanceof Variable) {
+ xObject = ((Variable)arg0).execute(xctxt);
+ }
+ else {
+ xObject = arg0.execute(xctxt);
+ }
+
+ if (xObject instanceof XPathArray) {
+ XPathArray xpathArr = (XPathArray)xObject;
+ List<XObject> nativeArr = xpathArr.getNativeArray();
+ Collections.reverse(nativeArr);
+ result = xpathArr;
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 1st argument of function array:reverse, needs to be an array.", srcLocator);
+ }
+
+ return result;
+ }
+
+}
diff --git a/src/org/apache/xpath/functions/array/FuncArrayTail.java b/src/org/apache/xpath/functions/array/FuncArrayTail.java
new file mode 100644
index 00000000..57c74e5e
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayTail.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.functions.array;
+
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FunctionOneArg;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+/**
+ * Implementation of the array:tail function.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FuncArrayTail extends FunctionOneArg {
+
+ private static final long serialVersionUID = 5783190267382201534L;
+
+ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+ {
+ XObject result = null;
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ Expression arg0 = getArg0();
+
+ XObject xObject = null;
+
+ if (arg0 instanceof Variable) {
+ xObject = ((Variable)arg0).execute(xctxt);
+ }
+ else {
+ xObject = arg0.execute(xctxt);
+ }
+
+ if (xObject instanceof XPathArray) {
+ XPathArray xpathArr = (XPathArray)xObject;
+ if (xpathArr.size() > 0) {
+ List<XObject> nativeArr = xpathArr.getNativeArray();
+
+ List<XObject> newNativeArr = nativeArr.subList(1, nativeArr.size());
+ xpathArr = new XPathArray();
+ xpathArr.setNativeArray(newNativeArr);
+
+ result = xpathArr;
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : An array:tail function call's argument "
+ + "cannot be an empty array.", srcLocator);
+ }
+ }
+ else {
+ throw new javax.xml.transform.TransformerException("FOAY0001 : The 1st argument of function array:tail, "
+ + "needs to be an array.", srcLocator);
+ }
+
+ return result;
+ }
+
+}
diff --git a/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java b/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java
index f0fb9ac9..267109ce 100644
--- a/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java
+++ b/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java
@@ -23,8 +23,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
/**
- * XPath 3.1 "function item" inline function expression test
- * cases.
+ * XPath 3.1 inline function expression test cases.
*
* @author Mukul Gandhi <mu...@apache.org>
*
diff --git a/tests/org/apache/xalan/xpath3/XPathArrayTests.java b/tests/org/apache/xalan/xpath3/XPathArrayTests.java
index bc9359a3..9f92a78f 100644
--- a/tests/org/apache/xalan/xpath3/XPathArrayTests.java
+++ b/tests/org/apache/xalan/xpath3/XPathArrayTests.java
@@ -127,5 +127,45 @@ public class XPathArrayTests extends XSLTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xslArrayTest9() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslArrayTest10() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test10.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslArrayTest11() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test11.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslArrayTest12() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test12.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
}
diff --git a/tests/org/apache/xalan/xpath3/XPathMapTests.java b/tests/org/apache/xalan/xpath3/XPathMapTests.java
index b0aae9a3..385bb3d3 100644
--- a/tests/org/apache/xalan/xpath3/XPathMapTests.java
+++ b/tests/org/apache/xalan/xpath3/XPathMapTests.java
@@ -207,5 +207,45 @@ public class XPathMapTests extends XSLTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xslMapTest17() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test17.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslMapTest18() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test18.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslMapTest19() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test19.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test19.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test19.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslMapTest20() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test20.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test20.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test20.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
}
diff --git a/tests/xpath_array/gold/test10.out b/tests/xpath_array/gold/test10.out
new file mode 100644
index 00000000..f301f596
--- /dev/null
+++ b/tests/xpath_array/gold/test10.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one resultSeqSize="1">5</one>
+ <two resultSeqSize="1">a b</two>
+</result>
diff --git a/tests/xpath_array/gold/test11.out b/tests/xpath_array/gold/test11.out
new file mode 100644
index 00000000..82dec5ce
--- /dev/null
+++ b/tests/xpath_array/gold/test11.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one resultArrSize="3">6 7 8</one>
+ <two resultArrSize="0"/>
+</result>
diff --git a/tests/xpath_array/gold/test12.out b/tests/xpath_array/gold/test12.out
new file mode 100644
index 00000000..f8002b89
--- /dev/null
+++ b/tests/xpath_array/gold/test12.out
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one>d c b a</one>
+</result>
diff --git a/tests/xpath_array/gold/test9.out b/tests/xpath_array/gold/test9.out
new file mode 100644
index 00000000..8b68129b
--- /dev/null
+++ b/tests/xpath_array/gold/test9.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one resultArrSize="5">a b x y c d</one>
+ <two resultArrSize="5">a b c d x y</two>
+ <three resultArrSize="5">a b x y c d</three>
+</result>
diff --git a/tests/xpath_array/test10.xsl b/tests/xpath_array/test10.xsl
new file mode 100644
index 00000000..e4939080
--- /dev/null
+++ b/tests/xpath_array/test10.xsl
@@ -0,0 +1,55 @@
+<?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:array="http://www.w3.org/2005/xpath-functions/array"
+ exclude-result-prefixes="xs array"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSLT 3.0 test case to test, XPath 3.1 function
+ array:head.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:variable name="arr1" select="[5, 6, 7, 8]" as="array(xs:integer)"/>
+
+ <xsl:variable name="arr2" select="['a', 'b']" as="array(xs:string)"/>
+ <xsl:variable name="arr3" select="['c', 'd']" as="array(xs:string)"/>
+
+ <xsl:variable name="arr4" select="[$arr2, $arr3]" as="array(*)"/>
+
+ <xsl:variable name="afterArrHead1" select="array:head($arr1)"/>
+ <xsl:variable name="afterArrHead2" select="array:head($arr4)"/>
+
+ <one resultSeqSize="{count($afterArrHead1)}">
+ <xsl:value-of select="$afterArrHead1"/>
+ </one>
+ <two resultSeqSize="{count($afterArrHead2)}">
+ <xsl:value-of select="$afterArrHead2"/>
+ </two>
+ </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/tests/xpath_array/test11.xsl b/tests/xpath_array/test11.xsl
new file mode 100644
index 00000000..51bd5c32
--- /dev/null
+++ b/tests/xpath_array/test11.xsl
@@ -0,0 +1,51 @@
+<?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:array="http://www.w3.org/2005/xpath-functions/array"
+ exclude-result-prefixes="xs array"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSLT 3.0 test case to test, XPath 3.1 function
+ array:tail.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:variable name="arr1" select="[5, 6, 7, 8]" as="array(xs:integer)"/>
+ <xsl:variable name="arr2" select="[5]" as="array(xs:integer)"/>
+
+ <xsl:variable name="afterArrTail1" select="array:tail($arr1)"/>
+ <xsl:variable name="afterArrTail2" select="array:tail($arr2)"/>
+
+ <one resultArrSize="{array:size($afterArrTail1)}">
+ <xsl:value-of select="$afterArrTail1"/>
+ </one>
+ <two resultArrSize="{array:size($afterArrTail2)}">
+ <xsl:value-of select="$afterArrTail2"/>
+ </two>
+ </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/tests/xpath_array/test12.xsl b/tests/xpath_array/test12.xsl
new file mode 100644
index 00000000..2dbfa0b6
--- /dev/null
+++ b/tests/xpath_array/test12.xsl
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:array="http://www.w3.org/2005/xpath-functions/array"
+ exclude-result-prefixes="xs array"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSLT 3.0 test case to test, XPath 3.1 function
+ array:reverse.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:variable name="arr1" select="['a', 'b', 'c', 'd']" as="array(xs:string)"/>
+ <one>
+ <xsl:value-of select="array:reverse($arr1)"/>
+ </one>
+ </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/tests/xpath_array/test9.xsl b/tests/xpath_array/test9.xsl
new file mode 100644
index 00000000..308504da
--- /dev/null
+++ b/tests/xpath_array/test9.xsl
@@ -0,0 +1,54 @@
+<?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:array="http://www.w3.org/2005/xpath-functions/array"
+ exclude-result-prefixes="xs array"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSLT 3.0 test case to test, XPath 3.1 function
+ array:insert-before.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:variable name="arr1" select="['a', 'b', 'c', 'd']" as="array(xs:string)"/>
+ <xsl:variable name="seq1" select="('x', 'y')" as="xs:string*"/>
+ <xsl:variable name="arr2" select="['x', 'y']" as="array(xs:string)"/>
+ <xsl:variable name="arrAfterInsertBefore1" select="array:insert-before($arr1, 3, $seq1)" as="array(*)"/>
+ <xsl:variable name="arrAfterInsertBefore2" select="array:insert-before($arr1, 5, $seq1)" as="array(*)"/>
+ <xsl:variable name="arrAfterInsertBefore3" select="array:insert-before($arr1, 3, $arr2)" as="array(*)"/>
+ <one resultArrSize="{array:size($arrAfterInsertBefore1)}">
+ <xsl:value-of select="$arrAfterInsertBefore1"/>
+ </one>
+ <two resultArrSize="{array:size($arrAfterInsertBefore2)}">
+ <xsl:value-of select="$arrAfterInsertBefore2"/>
+ </two>
+ <three resultArrSize="{array:size($arrAfterInsertBefore3)}">
+ <xsl:value-of select="$arrAfterInsertBefore3"/>
+ </three>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xpath_maps/gold/test17.out b/tests/xpath_maps/gold/test17.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test17.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one itemCount="2">
+ <ok>true ### true</ok>
+ </one>
+</result>
diff --git a/tests/xpath_maps/gold/test18.out b/tests/xpath_maps/gold/test18.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test18.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one itemCount="2">
+ <ok>true ### true</ok>
+ </one>
+</result>
diff --git a/tests/xpath_maps/gold/test19.out b/tests/xpath_maps/gold/test19.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test19.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one itemCount="2">
+ <ok>true ### true</ok>
+ </one>
+</result>
diff --git a/tests/xpath_maps/gold/test20.out b/tests/xpath_maps/gold/test20.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test20.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one itemCount="2">
+ <ok>true ### true</ok>
+ </one>
+</result>
diff --git a/tests/xpath_maps/test15.xsl b/tests/xpath_maps/test15.xsl
index 21fed8b0..240b0c45 100644
--- a/tests/xpath_maps/test15.xsl
+++ b/tests/xpath_maps/test15.xsl
@@ -18,12 +18,12 @@
<xsl:variable name="seq1" select="map:for-each($map1, $action1)"/>
<one itemCount="{count($seq1)}">
<ok>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="1"/>
</xsl:call-template>
<xsl:text> ### </xsl:text>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="2"/>
</xsl:call-template>
@@ -34,7 +34,7 @@
<!-- An XSL named template, to check whether a sequence
contains a specific value. -->
- <xsl:template name="exists" as="xs:boolean">
+ <xsl:template name="contains" as="xs:boolean">
<xsl:param name="seq1" as="xs:integer*"/>
<xsl:param name="value1" as="xs:integer"/>
<xsl:variable name="temp1">
diff --git a/tests/xpath_maps/test16.xsl b/tests/xpath_maps/test16.xsl
index 6d23b024..c84edc84 100644
--- a/tests/xpath_maps/test16.xsl
+++ b/tests/xpath_maps/test16.xsl
@@ -18,12 +18,12 @@
<xsl:variable name="seq1" select="distinct-values(map:for-each($map1, $action1))"/>
<one itemCount="{count($seq1)}">
<ok>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="'yes'"/>
</xsl:call-template>
<xsl:text> ### </xsl:text>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="'no'"/>
</xsl:call-template>
@@ -34,7 +34,7 @@
<!-- An XSL named template, to check whether a sequence
contains a specific value. -->
- <xsl:template name="exists" as="xs:boolean">
+ <xsl:template name="contains" as="xs:boolean">
<xsl:param name="seq1" as="xs:string*"/>
<xsl:param name="value1" as="xs:string"/>
<xsl:variable name="temp1">
diff --git a/tests/xpath_maps/test16.xsl b/tests/xpath_maps/test17.xsl
similarity index 66%
copy from tests/xpath_maps/test16.xsl
copy to tests/xpath_maps/test17.xsl
index 6d23b024..54c09a09 100644
--- a/tests/xpath_maps/test16.xsl
+++ b/tests/xpath_maps/test17.xsl
@@ -1,8 +1,9 @@
<?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:fn0="http://fn0"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
- exclude-result-prefixes="xs map"
+ exclude-result-prefixes="xs fn0 map"
version="3.0">
<!-- Author: mukulg@apache.org -->
@@ -18,42 +19,19 @@
<xsl:variable name="seq1" select="distinct-values(map:for-each($map1, $action1))"/>
<one itemCount="{count($seq1)}">
<ok>
- <xsl:call-template name="exists">
- <xsl:with-param name="seq1" select="$seq1"/>
- <xsl:with-param name="value1" select="'yes'"/>
- </xsl:call-template>
- <xsl:text> ### </xsl:text>
- <xsl:call-template name="exists">
- <xsl:with-param name="seq1" select="$seq1"/>
- <xsl:with-param name="value1" select="'no'"/>
- </xsl:call-template>
+ <xsl:value-of select="fn0:contains($seq1, 'yes')"/> ### <xsl:value-of select="fn0:contains($seq1, 'no')"/>
</ok>
</one>
</result>
</xsl:template>
- <!-- An XSL named template, to check whether a sequence
+ <!-- An XSL function, to check whether a sequence
contains a specific value. -->
- <xsl:template name="exists" as="xs:boolean">
+ <xsl:function name="fn0:contains" as="xs:boolean">
<xsl:param name="seq1" as="xs:string*"/>
<xsl:param name="value1" as="xs:string"/>
- <xsl:variable name="temp1">
- <xsl:for-each select="$seq1">
- <xsl:variable name="x1" select="."/>
- <xsl:if test="$x1 eq $value1">
- <yes/>
- </xsl:if>
- </xsl:for-each>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$temp1/yes">
- <xsl:value-of select="xs:boolean(1)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="xs:boolean(0)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
+ <xsl:sequence select="some $v1 in $seq1 satisfies $v1 eq $value1"/>
+ </xsl:function>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
diff --git a/tests/xpath_maps/test15.xsl b/tests/xpath_maps/test18.xsl
similarity index 66%
copy from tests/xpath_maps/test15.xsl
copy to tests/xpath_maps/test18.xsl
index 21fed8b0..66fe3a5b 100644
--- a/tests/xpath_maps/test15.xsl
+++ b/tests/xpath_maps/test18.xsl
@@ -1,8 +1,9 @@
<?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:fn0="http://fn0"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
- exclude-result-prefixes="xs map"
+ exclude-result-prefixes="xs fn0 map"
version="3.0">
<!-- Author: mukulg@apache.org -->
@@ -18,42 +19,19 @@
<xsl:variable name="seq1" select="map:for-each($map1, $action1)"/>
<one itemCount="{count($seq1)}">
<ok>
- <xsl:call-template name="exists">
- <xsl:with-param name="seq1" select="$seq1"/>
- <xsl:with-param name="value1" select="1"/>
- </xsl:call-template>
- <xsl:text> ### </xsl:text>
- <xsl:call-template name="exists">
- <xsl:with-param name="seq1" select="$seq1"/>
- <xsl:with-param name="value1" select="2"/>
- </xsl:call-template>
+ <xsl:value-of select="fn0:contains($seq1, 1)"/> ### <xsl:value-of select="fn0:contains($seq1, 2)"/>
</ok>
</one>
</result>
</xsl:template>
- <!-- An XSL named template, to check whether a sequence
+ <!-- An XSL function, to check whether a sequence
contains a specific value. -->
- <xsl:template name="exists" as="xs:boolean">
+ <xsl:function name="fn0:contains" as="xs:boolean">
<xsl:param name="seq1" as="xs:integer*"/>
<xsl:param name="value1" as="xs:integer"/>
- <xsl:variable name="temp1">
- <xsl:for-each select="$seq1">
- <xsl:variable name="x1" select="."/>
- <xsl:if test="$x1 eq $value1">
- <yes/>
- </xsl:if>
- </xsl:for-each>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$temp1/yes">
- <xsl:value-of select="xs:boolean(1)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="xs:boolean(0)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
+ <xsl:sequence select="some $v1 in $seq1 satisfies $v1 eq $value1"/>
+ </xsl:function>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
diff --git a/tests/xpath_maps/test15.xsl b/tests/xpath_maps/test19.xsl
similarity index 91%
copy from tests/xpath_maps/test15.xsl
copy to tests/xpath_maps/test19.xsl
index 21fed8b0..c37c3691 100644
--- a/tests/xpath_maps/test15.xsl
+++ b/tests/xpath_maps/test19.xsl
@@ -18,12 +18,12 @@
<xsl:variable name="seq1" select="map:for-each($map1, $action1)"/>
<one itemCount="{count($seq1)}">
<ok>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="1"/>
</xsl:call-template>
<xsl:text> ### </xsl:text>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="2"/>
</xsl:call-template>
@@ -33,17 +33,19 @@
</xsl:template>
<!-- An XSL named template, to check whether a sequence
- contains a specific value. -->
- <xsl:template name="exists" as="xs:boolean">
+ contains a specific value.
+ -->
+ <xsl:template name="contains" as="xs:boolean">
<xsl:param name="seq1" as="xs:integer*"/>
<xsl:param name="value1" as="xs:integer"/>
<xsl:variable name="temp1">
- <xsl:for-each select="$seq1">
+ <xsl:iterate select="$seq1">
<xsl:variable name="x1" select="."/>
<xsl:if test="$x1 eq $value1">
<yes/>
+ <xsl:break/>
</xsl:if>
- </xsl:for-each>
+ </xsl:iterate>
</xsl:variable>
<xsl:choose>
<xsl:when test="$temp1/yes">
diff --git a/tests/xpath_maps/test16.xsl b/tests/xpath_maps/test20.xsl
similarity index 91%
copy from tests/xpath_maps/test16.xsl
copy to tests/xpath_maps/test20.xsl
index 6d23b024..75d57586 100644
--- a/tests/xpath_maps/test16.xsl
+++ b/tests/xpath_maps/test20.xsl
@@ -18,12 +18,12 @@
<xsl:variable name="seq1" select="distinct-values(map:for-each($map1, $action1))"/>
<one itemCount="{count($seq1)}">
<ok>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="'yes'"/>
</xsl:call-template>
<xsl:text> ### </xsl:text>
- <xsl:call-template name="exists">
+ <xsl:call-template name="contains">
<xsl:with-param name="seq1" select="$seq1"/>
<xsl:with-param name="value1" select="'no'"/>
</xsl:call-template>
@@ -33,17 +33,19 @@
</xsl:template>
<!-- An XSL named template, to check whether a sequence
- contains a specific value. -->
- <xsl:template name="exists" as="xs:boolean">
+ contains a specific value.
+ -->
+ <xsl:template name="contains" as="xs:boolean">
<xsl:param name="seq1" as="xs:string*"/>
<xsl:param name="value1" as="xs:string"/>
<xsl:variable name="temp1">
- <xsl:for-each select="$seq1">
+ <xsl:iterate select="$seq1">
<xsl:variable name="x1" select="."/>
<xsl:if test="$x1 eq $value1">
<yes/>
+ <xsl:break/>
</xsl:if>
- </xsl:for-each>
+ </xsl:iterate>
</xsl:variable>
<xsl:choose>
<xsl:when test="$temp1/yes">
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org