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/28 14:24:04 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing an implementation of xpath 3.1 function fn:avg, along with few related working new test cases. also doing little bit of refactoring within xalanj codebase on this branch.

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 0d78f797 committing an implementation of xpath 3.1 function fn:avg, along with few related working new test cases. also doing little bit of refactoring within xalanj codebase on this branch.
     new 9100b69d Merge pull request #67 from mukulga/xalan-j_xslt3.0_mukul
0d78f797 is described below

commit 0d78f79779a2e7810abe2de44a6f5750597e1425
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Aug 28 19:47:19 2023 +0530

    committing an implementation of xpath 3.1 function fn:avg, along with few related working new test cases. also doing little bit of refactoring within xalanj codebase on this branch.
---
 .../xslt/util/XslTransformEvaluationHelper.java    | 154 ++++++++++++++++++++-
 src/org/apache/xpath/compiler/FunctionTable.java   |  10 +-
 src/org/apache/xpath/compiler/Keywords.java        |   5 +-
 src/org/apache/xpath/functions/FuncAvg.java        |  73 ++++++++++
 src/org/apache/xpath/functions/FuncCount.java      |  50 +------
 src/org/apache/xpath/functions/FuncSum.java        |  90 +-----------
 tests/fn_avg/gold/test1.out                        |   6 +
 tests/fn_avg/gold/test2.out                        |   4 +
 tests/fn_avg/test1.xsl                             |  58 ++++++++
 tests/fn_avg/test1_a.xml                           |   8 ++
 tests/fn_avg/test2.xsl                             |  50 +++++++
 tests/org/apache/xalan/xpath3/FnAvgTests.java      |  70 ++++++++++
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   4 +-
 13 files changed, 447 insertions(+), 135 deletions(-)

diff --git a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
index c08f5e71..d73bf38a 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
@@ -19,17 +19,26 @@ package org.apache.xalan.xslt.util;
 import java.util.List;
 
 import org.apache.xalan.templates.XMLNSDecl;
+import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.utils.XMLString;
+import org.apache.xpath.Expression;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.composite.ForExpr;
+import org.apache.xpath.composite.SimpleSequenceConstructor;
+import org.apache.xpath.functions.Function;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.operations.Range;
+import org.apache.xpath.operations.SimpleMapOperator;
+import org.apache.xpath.operations.Variable;
 import org.apache.xpath.xs.types.XSAnyType;
 import org.apache.xpath.xs.types.XSUntyped;
 import org.apache.xpath.xs.types.XSUntypedAtomic;
 
-import com.sun.org.apache.xml.internal.dtm.DTM;
-
 /**
  * This class, has few utility methods, to help with certain 
  * XalanJ XSLT transformation implementation tasks.
@@ -147,6 +156,147 @@ public class XslTransformEvaluationHelper {
         return resultSeq;
     }
     
+    /**
+     * Given a compiled XPath expression and an XPath context object, find
+     * the sum of values of xdm items represented by the provided compiled 
+     * XPath expression object. 
+     */
+    public static XNumber getSumOfValues(Expression expr, XPathContext xctxt) throws 
+                                                                  javax.xml.transform.TransformerException {        
+        double sum = 0.0;    
+        
+        if (expr instanceof Variable) {
+           Variable xslVariable = (Variable)expr;
+           XObject resultObj = xslVariable.execute(xctxt);
+           if (resultObj instanceof ResultSequence) {
+              ResultSequence resultSeq = (ResultSequence)resultObj;
+              sum = sumResultSequence(resultSeq);          
+           }       
+        }
+        else if (expr instanceof Function) {
+           XObject resultObj = ((Function)expr).execute(xctxt);
+           if (resultObj instanceof ResultSequence) {
+              ResultSequence resultSeq = (ResultSequence)resultObj;
+              sum = sumResultSequence(resultSeq);          
+           }  
+        }
+        else if (expr instanceof ForExpr) {
+           ForExpr forExpr = (ForExpr)expr;
+           ResultSequence forExprResult = (ResultSequence)(forExpr.execute(xctxt));
+           sum = sumResultSequence(forExprResult);
+        }
+        else if (expr instanceof SimpleSequenceConstructor) {
+           SimpleSequenceConstructor simpleSeqConstructor = (SimpleSequenceConstructor)expr;
+           ResultSequence seqCtrEvalResult = (ResultSequence)(simpleSeqConstructor.
+                                                                                execute(xctxt));
+           sum = sumResultSequence(seqCtrEvalResult);
+        }
+        else if (expr instanceof SimpleMapOperator) {
+           SimpleMapOperator simpleMapOperator = (SimpleMapOperator)expr;
+           ResultSequence simpleMapOperatorResult = (ResultSequence)(simpleMapOperator.
+                                                                                  execute(xctxt));
+           sum = sumResultSequence(simpleMapOperatorResult);
+        }
+        else {
+           int pos;
+            
+           DTMIterator nodes = expr.asIterator(xctxt, xctxt.getCurrentNode());
+
+           while ((pos = nodes.nextNode()) != DTM.NULL) {
+              DTM dtm = nodes.getDTM(pos);
+              XMLString xmlStr = dtm.getStringValue(pos);
+
+              if (xmlStr != null) {
+                 sum += xmlStr.toDouble();
+              }
+           }
+           nodes.detach();
+        }
+
+        return new XNumber(sum);    
+    }
+    
+    /**
+     * Given a compiled XPath expression object and an XPath context object, find
+     * the count of xdm items represented by the provided compiled XPath expression 
+     * object.  
+     */
+    public static XNumber getCountOfSequenceItems(Expression expr, XPathContext xctxt) throws 
+                                                                                  javax.xml.transform.TransformerException {
+        int count = 0;
+        
+        if (expr instanceof Function) {
+            XObject evalResult = ((Function)expr).execute(xctxt);
+            if (evalResult instanceof XNodeSet) {
+                count = ((XNodeSet)evalResult).getLength();   
+            }
+            else if (evalResult instanceof ResultSequence) {
+               count = ((ResultSequence)evalResult).size();
+            }
+        }
+        else if (expr instanceof Variable) {
+           XObject evalResult = ((Variable)expr).execute(xctxt);
+           if (evalResult instanceof XNodeSet) {
+               count = ((XNodeSet)evalResult).getLength();   
+           }
+           else if (evalResult instanceof ResultSequence) {
+              count = ((ResultSequence)evalResult).size();
+           }
+        }
+        else if (expr instanceof SimpleSequenceConstructor) {
+           SimpleSequenceConstructor simpleSeqConstructor = (SimpleSequenceConstructor)expr;
+           ResultSequence seqCtrEvalResult = (ResultSequence)(simpleSeqConstructor.
+                                                                                execute(xctxt));
+           count = seqCtrEvalResult.size();
+        }
+        else if (expr instanceof Expression) {
+            if (expr instanceof Range) {
+                ResultSequence resultSeq = (ResultSequence)(((Range)expr).execute(xctxt));
+                count = resultSeq.size();
+            }
+            else if (expr instanceof ForExpr) {
+                ResultSequence resultSeq = (ResultSequence)(((ForExpr)expr).execute(xctxt));
+                count = resultSeq.size();   
+            }
+            else {
+                DTMIterator nl = expr.asIterator(xctxt, xctxt.getCurrentNode());
+                count = nl.getLength(); 
+                nl.detach();
+            }
+        }
+    
+        return new XNumber((double)count);
+    }
+    
+    /**
+     * Summation of the values of ResultSequence data items.
+     *  
+     * @param resultSeq  The ResultSequence object instance, whose items
+     *                   need to be added to produce a summation value. 
+     * @return           The summation value with data type double.
+     */
+    private static double sumResultSequence(ResultSequence resultSeq) {
+       
+       double sum = 0.0;
+       
+       for (int idx = 0; idx < resultSeq.size(); idx++) {
+          XObject xObj = resultSeq.item(idx);
+          String str = null;
+          if (xObj instanceof XSAnyType) {
+             str = ((XSAnyType)xObj).stringValue();     
+          }
+          else {
+             str = xObj.str();
+          }
+          if (str != null) {
+             XString xStr = new XString(str);
+             sum +=  xStr.toDouble();
+          }
+       }
+       
+       return sum;
+    }
+    
     /**
      * Check whether a 'ResultSequence' object, contains a specific xdm item.
      */
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 6bcc12d0..e8e3b92b 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -308,6 +308,9 @@ public class FunctionTable
   
   /** The 'parse-xml-fragment()' id. */
   public static final int FUNC_PARSE_XML_FRAGMENT = 94;
+  
+  /** The 'avg()' id. */
+  public static final int FUNC_AVG = 95;
 
   // Proprietary
 
@@ -365,7 +368,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 = 95;
+  private static final int NUM_BUILT_IN_FUNCS = 96;
 
   /**
    * Number of built-in functions that may be added.
@@ -557,6 +560,8 @@ public class FunctionTable
     m_functions[FUNC_PARSE_XML_FRAGMENT] = 
       org.apache.xpath.functions.FuncParseXmlFragment.class;
     
+    m_functions[FUNC_AVG] = org.apache.xpath.functions.FuncAvg.class;
+    
   }
 
   static{
@@ -754,6 +759,9 @@ public class FunctionTable
                          new Integer(FunctionTable.FUNC_PARSE_XML));
          m_functionID.put(Keywords.FUNC_PARSE_XML_FRAGMENT,
                          new Integer(FunctionTable.FUNC_PARSE_XML_FRAGMENT));
+         
+         m_functionID.put(Keywords.FUNC_AVG,
+                         new Integer(FunctionTable.FUNC_AVG));
   }
   
   public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index f0b394c6..be9b8cde 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -419,6 +419,9 @@ public class Keywords
   /** parse-xml-fragment function string. */
   public static final String FUNC_PARSE_XML_FRAGMENT = "parse-xml-fragment";
   
+  /** avg function string. */
+  public static final String FUNC_AVG = "avg";
+  
   // Proprietary, built in functions
 
   /** current function string (Proprietary). */
@@ -476,8 +479,6 @@ public class Keywords
                     new Integer(OpCodes.NODETYPE_PI));
     m_nodetests.put(NODETYPE_NODE_STRING,
                     new Integer(OpCodes.NODETYPE_NODE));    
-    /*m_keywords.put(FUNC_KEY_STRING,
-                     new Integer(FunctionTable.FUNC_KEY));*/
   }
   
   static Object getAxisName(String key){
diff --git a/src/org/apache/xpath/functions/FuncAvg.java b/src/org/apache/xpath/functions/FuncAvg.java
new file mode 100644
index 00000000..00cf684b
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncAvg.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xpath.functions;
+
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * Implementation of an XPath 3.1 function fn:avg.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncAvg extends FunctionOneArg
+{
+
+  private static final long serialVersionUID = 6282866669363344636L;
+
+  /**
+   * 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
+  {          
+      XObject result = null;
+      
+      XNumber sumOfValues = XslTransformEvaluationHelper.getSumOfValues(
+                                                                     m_arg0, xctxt);
+      
+      XNumber countOfSeqItems = XslTransformEvaluationHelper.getCountOfSequenceItems(
+                                                                     m_arg0, xctxt);
+      if (countOfSeqItems.num() > 0) {
+         result = new XNumber(sumOfValues.num() / countOfSeqItems.num()); 
+      }
+      else {
+         // if this function's argument has evaluated to an empty sequence,
+         // the result of this function call is empty sequence.
+         result = new ResultSequence();
+      }
+      
+      // average calculation involving for example, xs:duration values and 
+      // its subtypes. TO DO
+      
+      return result;
+  }
+  
+}
diff --git a/src/org/apache/xpath/functions/FuncCount.java b/src/org/apache/xpath/functions/FuncCount.java
index c81f2b54..c57575f3 100644
--- a/src/org/apache/xpath/functions/FuncCount.java
+++ b/src/org/apache/xpath/functions/FuncCount.java
@@ -20,19 +20,13 @@
  */
 package org.apache.xpath.functions;
 
-import org.apache.xml.dtm.DTMIterator;
-import org.apache.xpath.Expression;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.composite.ForExpr;
-import org.apache.xpath.objects.ResultSequence;
-import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
-import org.apache.xpath.operations.Range;
-import org.apache.xpath.operations.Variable;
 
 /**
- * Execute the count() function.
+ * Implementation of an XPath function fn:count.
  * 
  * @xsl.usage advanced
  */
@@ -50,43 +44,9 @@ public class FuncCount extends FunctionOneArg
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
   {
-        int count = 0;
-        
-        if (m_arg0 instanceof Function) {
-            XObject evalResult = ((Function)m_arg0).execute(xctxt);
-            if (evalResult instanceof XNodeSet) {
-                count = ((XNodeSet)evalResult).getLength();   
-            }
-            else if (evalResult instanceof ResultSequence) {
-               count = ((ResultSequence)evalResult).size();
-            }
-        }
-        else if (m_arg0 instanceof Variable) {
-           XObject evalResult = ((Variable)m_arg0).execute(xctxt);
-           if (evalResult instanceof XNodeSet) {
-               count = ((XNodeSet)evalResult).getLength();   
-           }
-           else if (evalResult instanceof ResultSequence) {
-              count = ((ResultSequence)evalResult).size();
-           }
-        }
-        else if (m_arg0 instanceof Expression) {
-            if (m_arg0 instanceof Range) {
-                ResultSequence resultSeq = (ResultSequence)(((Range)m_arg0).execute(xctxt));
-                count = resultSeq.size();
-            }
-            else if (m_arg0 instanceof ForExpr) {
-                ResultSequence resultSeq = (ResultSequence)(((ForExpr)m_arg0).execute(xctxt));
-                count = resultSeq.size();   
-            }
-            else {
-                DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
-                count = nl.getLength();	
-                nl.detach();
-            }
-        }
-    
-        return new XNumber((double)count);    
+      XNumber result = XslTransformEvaluationHelper.getCountOfSequenceItems(m_arg0, xctxt);
+      
+      return result;    
   }
   
 }
diff --git a/src/org/apache/xpath/functions/FuncSum.java b/src/org/apache/xpath/functions/FuncSum.java
index 2436087a..09f3b323 100644
--- a/src/org/apache/xpath/functions/FuncSum.java
+++ b/src/org/apache/xpath/functions/FuncSum.java
@@ -20,21 +20,14 @@
  */
 package org.apache.xpath.functions;
 
-import org.apache.xml.dtm.DTM;
-import org.apache.xml.dtm.DTMIterator;
-import org.apache.xml.utils.XMLString;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.composite.ForExpr;
-import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
-import org.apache.xpath.objects.XString;
-import org.apache.xpath.operations.SimpleMapOperator;
-import org.apache.xpath.operations.Variable;
-import org.apache.xpath.xs.types.XSAnyType;
 
 /**
- * Execute the Sum() function.
+ * Implementation of an XPath function fn:sum.
+ * 
  * @xsl.usage advanced
  */
 public class FuncSum extends FunctionOneArg
@@ -50,80 +43,9 @@ public class FuncSum extends FunctionOneArg
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
-  {
-    
-    double sum = 0.0;    
-    
-    if (m_arg0 instanceof Variable) {
-       Variable xslVariable = (Variable)m_arg0;
-       XObject resultObj = xslVariable.execute(xctxt);
-       if (resultObj instanceof ResultSequence) {
-          ResultSequence resultSeq = (ResultSequence)resultObj;
-          sum = sumResultSequence(resultSeq);          
-       }       
-    }
-    else if (m_arg0 instanceof Function) {
-       XObject resultObj = ((Function)m_arg0).execute(xctxt);
-       if (resultObj instanceof ResultSequence) {
-          ResultSequence resultSeq = (ResultSequence)resultObj;
-          sum = sumResultSequence(resultSeq);          
-       }  
-    }
-    else if (m_arg0 instanceof ForExpr) {
-       ForExpr forExpr = (ForExpr)m_arg0;
-       ResultSequence forExprResult = (ResultSequence)(forExpr.execute(xctxt));
-       sum = sumResultSequence(forExprResult);
-    }
-    else if (m_arg0 instanceof SimpleMapOperator) {
-       SimpleMapOperator simpleMapOperator = (SimpleMapOperator)m_arg0;
-       ResultSequence simpleMapOperatorResult = (ResultSequence)(simpleMapOperator.
-                                                                              execute(xctxt));
-       sum = sumResultSequence(simpleMapOperatorResult);
-    }
-    else {
-       int pos;
-        
-       DTMIterator nodes = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
-
-       while (DTM.NULL != (pos = nodes.nextNode())) {
-          DTM dtm = nodes.getDTM(pos);
-          XMLString xmlStr = dtm.getStringValue(pos);
-
-          if (xmlStr != null) {
-             sum += xmlStr.toDouble();
-          }
-       }
-       nodes.detach();
-    }
-
-    return new XNumber(sum);
-  }
-  
-  /**
-   * Summation of the values of ResultSequence data items.
-   *  
-   * @param resultSeq  The ResultSequence object instance, whose items
-   *                   need to be added to produce a summation value. 
-   * @return           The summation value with data type double.
-   */
-  private double sumResultSequence(ResultSequence resultSeq) {
-     double sum = 0.0;
-     
-     for (int idx = 0; idx < resultSeq.size(); idx++) {
-        XObject xObj = resultSeq.item(idx);
-        String str = null;
-        if (xObj instanceof XSAnyType) {
-           str = ((XSAnyType)xObj).stringValue();     
-        }
-        else {
-           str = xObj.str();
-        }
-        if (str != null) {
-           XString xStr = new XString(str);
-           sum +=  xStr.toDouble();
-        }
-     }
+  {    
+     XNumber result = XslTransformEvaluationHelper.getSumOfValues(m_arg0, xctxt);
      
-     return sum;
+     return result;    
   }
 }
diff --git a/tests/fn_avg/gold/test1.out b/tests/fn_avg/gold/test1.out
new file mode 100644
index 00000000..b5f15a68
--- /dev/null
+++ b/tests/fn_avg/gold/test1.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>4</one>
+  <two/>
+  <three>NaN</three>
+  <four>NaN</four>
+</result>
diff --git a/tests/fn_avg/gold/test2.out b/tests/fn_avg/gold/test2.out
new file mode 100644
index 00000000..68af2fe6
--- /dev/null
+++ b/tests/fn_avg/gold/test2.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>2.7199999999999998</one>
+  <two>4.433333333333334</two>
+</result>
diff --git a/tests/fn_avg/test1.xsl b/tests/fn_avg/test1.xsl
new file mode 100644
index 00000000..916cb5ca
--- /dev/null
+++ b/tests/fn_avg/test1.xsl
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet test, for the XPath 3.1 function fn:avg.
+        
+        The XPath function fn:avg's usage examples, as illustrated
+        within this stylesheet are borrowed from XPath 3.1 F&O spec. 
+   -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="seq1" select="(3, 4, 5)"/>
+    
+    <xsl:variable name="seq2" select="(xs:float('INF'), xs:float('-INF'))"/>
+    
+    <xsl:variable name="seq3" select="($seq1, xs:float('NaN'))"/>
+    
+    <xsl:template match="/">
+       <result>
+         <one>
+            <xsl:value-of select="avg($seq1)"/> 
+         </one>
+         <two>
+            <xsl:value-of select="avg(())"/>
+         </two>
+         <three>
+	        <xsl:value-of select="avg($seq2)"/>
+         </three>
+         <four>
+	        <xsl:value-of select="avg($seq3)"/>
+         </four>
+       </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_avg/test1_a.xml b/tests/fn_avg/test1_a.xml
new file mode 100644
index 00000000..0bf910bc
--- /dev/null
+++ b/tests/fn_avg/test1_a.xml
@@ -0,0 +1,8 @@
+<info>
+  <a>1</a>
+  <b>1.3</b>
+  <c>2</c>
+  <d>2.3</d>
+  <e>7</e>
+  <data val1="1" val2="2.3" val3="10"/>
+</info>
\ No newline at end of file
diff --git a/tests/fn_avg/test2.xsl b/tests/fn_avg/test2.xsl
new file mode 100644
index 00000000..93003b2d
--- /dev/null
+++ b/tests/fn_avg/test2.xsl
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+  
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet test, for the XPath 3.1 function fn:avg.
+        
+        This stylesheet reads input data to be processed, from an
+        XML external document. 
+   -->                 
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:template match="/info">
+       <result>
+         <one>
+            <!-- process all XML sibling elements except an 
+                 element named 'data'. -->
+            <xsl:value-of select="avg(*[not(self::data)])"/> 
+         </one>
+         <two>
+            <!-- process all the attributes of an XML
+                 element named 'data'. -->
+            <xsl:value-of select="avg(data/@*)"/>
+         </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/org/apache/xalan/xpath3/FnAvgTests.java b/tests/org/apache/xalan/xpath3/FnAvgTests.java
new file mode 100644
index 00000000..df139582
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/FnAvgTests.java
@@ -0,0 +1,70 @@
+/*
+ * 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.xpath3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.apache.xalan.xslt3.XSLConstants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XPath 3.1 function fn:avg test cases.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FnAvgTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "fn_avg/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "fn_avg/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 xslFnAvgTest1() {
+        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 xslFnAvgTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.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 6a31fe8c..660dee97 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -19,6 +19,7 @@ package org.apache.xalan.xslt3;
 import org.apache.xalan.xpath3.BuiltinFunctionsNamespceTests;
 import org.apache.xalan.xpath3.DynamicFunctionCallTests;
 import org.apache.xalan.xpath3.FnAbsTests;
+import org.apache.xalan.xpath3.FnAvgTests;
 import org.apache.xalan.xpath3.FnCodepointEqualTests;
 import org.apache.xalan.xpath3.FnCodepointsToStringTests;
 import org.apache.xalan.xpath3.FnCompareTests;
@@ -86,7 +87,8 @@ import org.junit.runners.Suite.SuiteClasses;
                 NodeComparisonTests.class, SimpleMapOperatorTests.class, FnFoldLeftTests.class,
                 FnFoldRightTests.class, FnForEachPairTests.class, FnSortTests.class, FnCodepointsToStringTests.class,
                 FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
-                SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class, TemplateTests.class})
+                SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
+                TemplateTests.class, FnAvgTests.class })
 public class AllXsl3Tests {
 
 }


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