You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/08/24 09:37:59 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: implementing the xpath 3.1 function fn:unordered. improving the implementations of xpath 3.1 functions fn:insert-before, fn:subsequence. adding few new working test cases for function fn:sort.
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 f5f685b5 implementing the xpath 3.1 function fn:unordered. improving the implementations of xpath 3.1 functions fn:insert-before, fn:subsequence. adding few new working test cases for function fn:sort.
new 14b0ead9 Merge pull request #59 from mukulga/xalan-j_xslt3.0_mukul
f5f685b5 is described below
commit f5f685b5eb920703544979c44914b451a42f15f8
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Thu Aug 24 15:03:18 2023 +0530
implementing the xpath 3.1 function fn:unordered. improving the implementations of xpath 3.1 functions fn:insert-before, fn:subsequence. adding few new working test cases for function fn:sort.
---
src/org/apache/xpath/compiler/FunctionTable.java | 9 ++-
src/org/apache/xpath/compiler/Keywords.java | 3 +
.../apache/xpath/functions/FuncInsertBefore.java | 44 +++++++++-----
.../apache/xpath/functions/FuncSubsequence.java | 18 +++---
src/org/apache/xpath/functions/FuncUnordered.java | 71 ++++++++++++++++++++++
src/org/apache/xpath/objects/ResultSequence.java | 20 ++++++
tests/fn_sort/gold/test14.out | 4 ++
tests/fn_sort/gold/test15.out | 36 +++++++++++
tests/fn_sort/test17.xsl | 43 +++++++++++++
tests/fn_sort/test18.xsl | 45 ++++++++++++++
tests/fn_sort/test1_h.xml | 17 ++++++
tests/org/apache/xalan/xpath3/FnSortTests.java | 20 ++++++
tests/org/apache/xalan/xslt3/AllXsl3Tests.java | 2 +-
13 files changed, 307 insertions(+), 25 deletions(-)
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 40a4b113..b7ebd456 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -299,6 +299,9 @@ public class FunctionTable
/** The 'subsequence()' id. */
public static final int FUNC_SUBSEQUENCE = 91;
+
+ /** The 'unordered()' id. */
+ public static final int FUNC_UNORDERED = 92;
// Proprietary
@@ -356,7 +359,7 @@ public class FunctionTable
* Number of built in functions. Be sure to update this as
* built-in functions are added.
*/
- private static final int NUM_BUILT_IN_FUNCS = 92;
+ private static final int NUM_BUILT_IN_FUNCS = 93;
/**
* Number of built-in functions that may be added.
@@ -541,6 +544,8 @@ public class FunctionTable
org.apache.xpath.functions.FuncReverse.class;
m_functions[FUNC_SUBSEQUENCE] =
org.apache.xpath.functions.FuncSubsequence.class;
+ m_functions[FUNC_UNORDERED] =
+ org.apache.xpath.functions.FuncUnordered.class;
}
static{
@@ -733,6 +738,8 @@ public class FunctionTable
new Integer(FunctionTable.FUNC_REVERSE));
m_functionID.put(Keywords.FUNC_SUBSEQUENCE,
new Integer(FunctionTable.FUNC_SUBSEQUENCE));
+ m_functionID.put(Keywords.FUNC_UNORDERED,
+ new Integer(FunctionTable.FUNC_UNORDERED));
}
public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index 9a5ff0a4..f83a1a5b 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -410,6 +410,9 @@ public class Keywords
/** subsequence function string. */
public static final String FUNC_SUBSEQUENCE = "subsequence";
+ /** unordered function string. */
+ public static final String FUNC_UNORDERED = "unordered";
+
// Proprietary, built in functions
/** current function string (Proprietary). */
diff --git a/src/org/apache/xpath/functions/FuncInsertBefore.java b/src/org/apache/xpath/functions/FuncInsertBefore.java
index 060b6060..bcd92c4a 100644
--- a/src/org/apache/xpath/functions/FuncInsertBefore.java
+++ b/src/org/apache/xpath/functions/FuncInsertBefore.java
@@ -59,26 +59,40 @@ public class FuncInsertBefore extends Function3Args {
ResultSequence rsArg0 = XslTransformEvaluationHelper.getResultSequenceFromXObject(
xObject0, xctxt);
-
- int seqInsertPos = getSequenceInsertPosition(xObject1);
-
- if (seqInsertPos < 1) {
- seqInsertPos = 1;
- }
-
ResultSequence rsArg2 = XslTransformEvaluationHelper.getResultSequenceFromXObject(
xObject2, xctxt);
- for (int idx = 0; idx < (seqInsertPos - 1); idx++) {
- result.add(rsArg0.item(idx));
+ if (rsArg0.size() == 0) {
+ for (int idx = 0; idx < rsArg2.size(); idx++) {
+ result.add(rsArg2.item(idx));
+ }
}
-
- for (int idx = 0; idx < rsArg2.size(); idx++) {
- result.add(rsArg2.item(idx));
+ else if (rsArg2.size() == 0) {
+ for (int idx = 0; idx < rsArg0.size(); idx++) {
+ result.add(rsArg0.item(idx));
+ }
}
-
- for (int idx = (seqInsertPos - 1); idx < rsArg0.size(); idx++) {
- result.add(rsArg0.item(idx));
+ else {
+ int seqInsertPos = getSequenceInsertPosition(xObject1);
+
+ if (seqInsertPos < 1) {
+ seqInsertPos = 1;
+ }
+ else if (seqInsertPos > rsArg0.size()) {
+ seqInsertPos = rsArg0.size() + 1;
+ }
+
+ for (int idx = 0; idx < (seqInsertPos - 1); idx++) {
+ result.add(rsArg0.item(idx));
+ }
+
+ for (int idx = 0; idx < rsArg2.size(); idx++) {
+ result.add(rsArg2.item(idx));
+ }
+
+ for (int idx = (seqInsertPos - 1); idx < rsArg0.size(); idx++) {
+ result.add(rsArg0.item(idx));
+ }
}
}
catch (TransformerException ex) {
diff --git a/src/org/apache/xpath/functions/FuncSubsequence.java b/src/org/apache/xpath/functions/FuncSubsequence.java
index 6e98c692..9a662a4f 100644
--- a/src/org/apache/xpath/functions/FuncSubsequence.java
+++ b/src/org/apache/xpath/functions/FuncSubsequence.java
@@ -73,6 +73,8 @@ public class FuncSubsequence extends FunctionMultiArgs {
XObject arg1Obj = arg1.execute(xctxt);
int startingLoc = getIntFromXObject(arg1Obj);
+ startingLoc = (startingLoc <= 0) ? 1 : startingLoc;
+
// This function call requires either two arguments, or three arguments
if (numOfArgs == 2) {
for (int idx = (startingLoc - 1); idx < rsArg0.size(); idx++) {
@@ -84,15 +86,15 @@ public class FuncSubsequence extends FunctionMultiArgs {
arg2 = m_arg2;
XObject arg2Obj = arg2.execute(xctxt);
int lengthVal = getIntFromXObject(arg2Obj);
- if (lengthVal > rsArg0.size()) {
- throw new javax.xml.transform.TransformerException("FORG0006 : The third argument value " +
- lengthVal + " of call to function fn:subsequence, is "
- + "greater than the size of input sequence.");
+ if (lengthVal < 0) {
+ lengthVal = 0;
+ }
+ else if ((startingLoc + lengthVal) > rsArg0.size()) {
+ lengthVal = rsArg0.size() - startingLoc + 1;
}
- else {
- for (int idx = (startingLoc - 1); idx < ((startingLoc - 1) + lengthVal); idx++) {
- result.add(rsArg0.item(idx));
- }
+
+ for (int idx = (startingLoc - 1); idx < ((startingLoc - 1) + lengthVal); idx++) {
+ result.add(rsArg0.item(idx));
}
}
}
diff --git a/src/org/apache/xpath/functions/FuncUnordered.java b/src/org/apache/xpath/functions/FuncUnordered.java
new file mode 100644
index 00000000..e235cc2d
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncUnordered.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implementation of the unordered() function.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FuncUnordered extends FunctionOneArg {
+
+ private static final long serialVersionUID = 4192924071383539197L;
+
+ /**
+ * Execute the function. The function must return a valid object.
+ *
+ * @param xctxt The current execution context.
+ * @return A valid XObject.
+ *
+ * @throws javax.xml.transform.TransformerException
+ */
+ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+ {
+
+ ResultSequence result = new ResultSequence();
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ XObject xObject0 = m_arg0.execute(xctxt);
+
+ ResultSequence rsArg0 = XslTransformEvaluationHelper.getResultSequenceFromXObject(
+ xObject0, xctxt);
+ List<XObject> sequenceAsList = rsArg0.getResultSequenceItems();
+
+ // randomly permute the list of input sequence items
+ Collections.shuffle(sequenceAsList);
+
+ for (int idx = 0; idx < sequenceAsList.size(); idx++) {
+ result.add(sequenceAsList.get(idx));
+ }
+
+ return result;
+ }
+
+}
diff --git a/src/org/apache/xpath/objects/ResultSequence.java b/src/org/apache/xpath/objects/ResultSequence.java
index 0e106c18..09b2dfbf 100644
--- a/src/org/apache/xpath/objects/ResultSequence.java
+++ b/src/org/apache/xpath/objects/ResultSequence.java
@@ -46,18 +46,38 @@ public class ResultSequence extends XObject
return CLASS_RESULT_SEQUENCE;
}
+ /**
+ * Append an item at the end of the sequence.
+ */
public void add(XObject item) {
rsList.add(item);
}
+ /**
+ * Set an item at a particular index.
+ */
+ public void set(int idx, XObject item) {
+ rsList.set(idx, item);
+ }
+
+ /**
+ * Get an item stored at a particular index.
+ */
public XObject item(int idx) {
return rsList.get(idx);
}
+ /**
+ * Get the size of the current sequence object.
+ */
public int size() {
return rsList.size();
}
+ /**
+ * Get the contents of this sequence object, as list of
+ * XObject objects.
+ */
public List<XObject> getResultSequenceItems() {
return rsList;
}
diff --git a/tests/fn_sort/gold/test14.out b/tests/fn_sort/gold/test14.out
new file mode 100644
index 00000000..b48c6680
--- /dev/null
+++ b/tests/fn_sort/gold/test14.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one sortOrder="ascending">a b p q</one>
+ <two sortOrder="descending">q p b a</two>
+</result>
diff --git a/tests/fn_sort/gold/test15.out b/tests/fn_sort/gold/test15.out
new file mode 100644
index 00000000..8cb46bde
--- /dev/null
+++ b/tests/fn_sort/gold/test15.out
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one sortOrder="ascending">
+ <part id="1">
+ <name>pqr</name>
+ </part>
+ <part id="2">
+ <name>mno</name>
+ </part>
+ <part id="3">
+ <name>abc</name>
+ </part>
+ <part id="4">
+ <name>lmn</name>
+ </part>
+ <part id="5">
+ <name>xyz</name>
+ </part>
+ </one>
+ <two sortOrder="descending">
+ <part id="5">
+ <name>xyz</name>
+ </part>
+ <part id="4">
+ <name>lmn</name>
+ </part>
+ <part id="3">
+ <name>abc</name>
+ </part>
+ <part id="2">
+ <name>mno</name>
+ </part>
+ <part id="1">
+ <name>pqr</name>
+ </part>
+ </two>
+</result>
diff --git a/tests/fn_sort/test17.xsl b/tests/fn_sort/test17.xsl
new file mode 100644
index 00000000..2462cfd9
--- /dev/null
+++ b/tests/fn_sort/test17.xsl
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSLT stylesheet test case, to test an XPath 3.1 function
+ fn:sort which produces the result in an ascending order of input
+ sequence items, and producing a descending ordered sort result
+ of input sequence items using the function fn:reverse on result
+ of call to function fn:sort. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:variable name="seq1" select="('p','a','b','q')"/>
+
+ <xsl:template match="/">
+ <xsl:variable name="sortResult" select="sort($seq1, ())"/>
+ <result>
+ <one sortOrder="ascending"><xsl:value-of select="$sortResult"/></one>
+ <two sortOrder="descending"><xsl:value-of select="reverse($sortResult)"/></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>
\ No newline at end of file
diff --git a/tests/fn_sort/test18.xsl b/tests/fn_sort/test18.xsl
new file mode 100644
index 00000000..c18dfead
--- /dev/null
+++ b/tests/fn_sort/test18.xsl
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_h.xml -->
+
+ <!-- An XSLT stylesheet test case, to test an XPath 3.1 function
+ fn:sort which produces the result in an ascending order of input
+ sequence items, and producing a descending ordered sort result
+ of input sequence items using the function fn:reverse on result
+ of call to function fn:sort. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/info">
+ <xsl:variable name="sortResult" select="sort(part, (), function($part) { xs:integer($part/@id) })"/>
+ <result>
+ <one sortOrder="ascending"><xsl:copy-of select="$sortResult"/></one>
+ <two sortOrder="descending"><xsl:copy-of select="reverse($sortResult)"/></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>
\ No newline at end of file
diff --git a/tests/fn_sort/test1_h.xml b/tests/fn_sort/test1_h.xml
new file mode 100644
index 00000000..b5b457a9
--- /dev/null
+++ b/tests/fn_sort/test1_h.xml
@@ -0,0 +1,17 @@
+<info>
+ <part id="3">
+ <name>abc</name>
+ </part>
+ <part id="2">
+ <name>mno</name>
+ </part>
+ <part id="1">
+ <name>pqr</name>
+ </part>
+ <part id="5">
+ <name>xyz</name>
+ </part>
+ <part id="4">
+ <name>lmn</name>
+ </part>
+</info>
\ No newline at end of file
diff --git a/tests/org/apache/xalan/xpath3/FnSortTests.java b/tests/org/apache/xalan/xpath3/FnSortTests.java
index 10aed336..d8373c92 100644
--- a/tests/org/apache/xalan/xpath3/FnSortTests.java
+++ b/tests/org/apache/xalan/xpath3/FnSortTests.java
@@ -208,5 +208,25 @@ public class FnSortTests extends XslTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xslFnSortTest17() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test14.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslFnSortTest18() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_h.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test15.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
}
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 9f90c976..d6e50b02 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -17,7 +17,6 @@
package org.apache.xalan.xslt3;
import org.apache.xalan.xpath3.BuiltinFunctionsNamespceTests;
-import org.apache.xalan.xpath3.XsDurationComponentExtractionFunctionTests;
import org.apache.xalan.xpath3.DynamicFunctionCallTests;
import org.apache.xalan.xpath3.FnAbsTests;
import org.apache.xalan.xpath3.FnCodepointEqualTests;
@@ -52,6 +51,7 @@ import org.apache.xalan.xpath3.TrignometricAndExponentialFunctionTests;
import org.apache.xalan.xpath3.ValueComparisonTests;
import org.apache.xalan.xpath3.XPathArithmeticOnDurationValuesTests;
import org.apache.xalan.xpath3.XsConstructorFunctionTests;
+import org.apache.xalan.xpath3.XsDurationComponentExtractionFunctionTests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org