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/26 14:54:47 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 function fn:parse-xml, and few new working related 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 61174749 committing implementation of xpath 3.1 function fn:parse-xml, and few new working related test cases as well
     new 5f36b653 Merge pull request #64 from mukulga/xalan-j_xslt3.0_mukul
61174749 is described below

commit 6117474925f0be4f838e2b5e3f21c9fbd863a948
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Aug 26 20:20:49 2023 +0530

    committing implementation of xpath 3.1 function fn:parse-xml, and few new working related test cases as well
---
 src/org/apache/xpath/compiler/FunctionTable.java   |  23 +++--
 src/org/apache/xpath/compiler/Keywords.java        |   3 +
 src/org/apache/xpath/functions/FuncParseXml.java   | 106 +++++++++++++++++++++
 tests/fn_parse_xml/gold/test1.out                  |   3 +
 tests/fn_parse_xml/gold/test2.out                  |   9 ++
 tests/fn_parse_xml/test1.xsl                       |  47 +++++++++
 tests/fn_parse_xml/test2.xsl                       |  76 +++++++++++++++
 tests/org/apache/xalan/xpath3/FnParseXmlTests.java |  72 ++++++++++++++
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   3 +-
 9 files changed, 333 insertions(+), 9 deletions(-)

diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index b7ebd456..ded47104 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -302,6 +302,9 @@ public class FunctionTable
   
   /** The 'unordered()' id. */
   public static final int FUNC_UNORDERED = 92;
+  
+  /** The 'parse-xml()' id. */
+  public static final int FUNC_PARSE_XML = 93;
 
   // Proprietary
 
@@ -359,7 +362,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 = 93;
+  private static final int NUM_BUILT_IN_FUNCS = 94;
 
   /**
    * Number of built-in functions that may be added.
@@ -425,6 +428,7 @@ public class FunctionTable
       org.apache.xpath.functions.FuncDoclocation.class;
     m_functions[FUNC_UNPARSED_ENTITY_URI] =
       org.apache.xpath.functions.FuncUnparsedEntityURI.class;
+    
     m_functions[FUNC_MATCHES] = 
       org.apache.xpath.functions.FuncMatches.class;
     m_functions[FUNC_REPLACE] = 
@@ -473,8 +477,8 @@ public class FunctionTable
     m_functions[FUNC_SORT] = 
       org.apache.xpath.functions.FuncSort.class;
     
-    // XPath 3.1 functions configurations for the math functions 
-    // namespace http://www.w3.org/2005/xpath-functions/math.
+    // XPath 3.1 built-in functions configurations for the math 
+    // functions namespace http://www.w3.org/2005/xpath-functions/math    
     m_functions[FUNC_MATH_PI] = 
       org.apache.xpath.functions.math.FuncMathPi.class;
     m_functions[FUNC_MATH_EXP] = 
@@ -504,8 +508,6 @@ public class FunctionTable
     m_functions[FUNC_MATH_ATAN2] = 
       org.apache.xpath.functions.math.FuncMathAtan2.class;
     
-    // XPath 3.1 functions configurations for component 
-    // extraction functions on duration values.
     m_functions[FUNC_YEARS_FROM_DURATION] = 
       org.apache.xpath.functions.FuncYearsFromDuration.class;
     m_functions[FUNC_MONTHS_FROM_DURATION] = 
@@ -546,6 +548,10 @@ public class FunctionTable
       org.apache.xpath.functions.FuncSubsequence.class;
     m_functions[FUNC_UNORDERED] = 
       org.apache.xpath.functions.FuncUnordered.class;
+    
+    m_functions[FUNC_PARSE_XML] = 
+      org.apache.xpath.functions.FuncParseXml.class;
+    
   }
 
   static{
@@ -668,7 +674,7 @@ public class FunctionTable
                           new Integer(FunctionTable.FUNC_SORT));
           
           // XPath 3.1 functions configurations for the math functions 
-          // namespace http://www.w3.org/2005/xpath-functions/math.
+          // namespace http://www.w3.org/2005/xpath-functions/math
           m_functionID.put(Keywords.FUNC_MATH_PI,
                           new Integer(FunctionTable.FUNC_MATH_PI));
           m_functionID.put(Keywords.FUNC_MATH_EXP,
@@ -698,8 +704,6 @@ public class FunctionTable
           m_functionID.put(Keywords.FUNC_MATH_ATAN2,
                          new Integer(FunctionTable.FUNC_MATH_ATAN2));
           
-         // XPath 3.1 functions configurations for component 
-         // extraction functions on xdm duration values.
          m_functionID.put(Keywords.FUNC_YEARS_FROM_DURATION,
                          new Integer(FunctionTable.FUNC_YEARS_FROM_DURATION));
          m_functionID.put(Keywords.FUNC_MONTHS_FROM_DURATION,
@@ -740,6 +744,9 @@ public class FunctionTable
                          new Integer(FunctionTable.FUNC_SUBSEQUENCE));
          m_functionID.put(Keywords.FUNC_UNORDERED,
                          new Integer(FunctionTable.FUNC_UNORDERED));
+         
+         m_functionID.put(Keywords.FUNC_PARSE_XML,
+                         new Integer(FunctionTable.FUNC_PARSE_XML));
   }
   
   public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index f83a1a5b..2befeee8 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -413,6 +413,9 @@ public class Keywords
   /** unordered function string. */
   public static final String FUNC_UNORDERED = "unordered";
   
+  /** parse-xml function string. */
+  public static final String FUNC_PARSE_XML = "parse-xml";
+  
   // Proprietary, built in functions
 
   /** current function string (Proprietary). */
diff --git a/src/org/apache/xpath/functions/FuncParseXml.java b/src/org/apache/xpath/functions/FuncParseXml.java
new file mode 100644
index 00000000..ea5f4571
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncParseXml.java
@@ -0,0 +1,106 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.dom.DOMSource;
+
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.DTM;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Document;
+
+/**
+ * Implementation of the parse-xml() function.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncParseXml extends FunctionOneArg {
+
+    private static final long serialVersionUID = -6262670777202140694L;
+
+    /**
+     * 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;
+        
+        SourceLocator srcLocator = xctxt.getSAXLocator();
+
+        try {
+            XObject xObject0 = m_arg0.execute(xctxt);
+            
+            String argStrVal = XslTransformEvaluationHelper.getStrVal(xObject0);
+            
+            result = getNodeSetFromStr(argStrVal, xctxt);
+        }
+        catch (javax.xml.transform.TransformerException ex) {
+            throw new javax.xml.transform.TransformerException(ex.getMessage(), srcLocator);   
+        }
+        
+        return result;
+    }
+    
+    /**
+     * Get an XDM nodeset corresponding to an XML string value.
+     */
+    private XNodeSet getNodeSetFromStr(String strVal, XPathContext xctxt) throws 
+                                                          javax.xml.transform.TransformerException {
+        XNodeSet nodeSet = null;
+        
+        try {
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            
+            // make the XML namespace processing active, on an XML parse 
+            // of the string value.
+            dbf.setNamespaceAware(true);         
+            
+            DocumentBuilder dBuilder = dbf.newDocumentBuilder();
+            
+            InputStream inpStream = new ByteArrayInputStream(strVal.getBytes(
+                                                                      StandardCharsets.UTF_8));
+            Document xmlDocument = dBuilder.parse(inpStream);
+            
+            DTM dtm = xctxt.getDTM(new DOMSource(xmlDocument), true, null, false, false);            
+            int documentNodeHandleVal = dtm.getDocument();
+            
+            nodeSet = new XNodeSet(documentNodeHandleVal, xctxt.getDTMManager());
+        }
+        catch (Exception ex) {
+           throw new javax.xml.transform.TransformerException("FODC0006 : " + ex.getMessage()); 
+        }
+        
+        return nodeSet;
+    }
+
+}
diff --git a/tests/fn_parse_xml/gold/test1.out b/tests/fn_parse_xml/gold/test1.out
new file mode 100644
index 00000000..510cb6b6
--- /dev/null
+++ b/tests/fn_parse_xml/gold/test1.out
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <alpha>abcd</alpha>
+</result>
diff --git a/tests/fn_parse_xml/gold/test2.out b/tests/fn_parse_xml/gold/test2.out
new file mode 100644
index 00000000..45bd0f70
--- /dev/null
+++ b/tests/fn_parse_xml/gold/test2.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <alpha>
+    <a strLen="5">hello</a>
+    <b strLen="5">world</b>
+    <c strLen="4">this</c>
+    <d strLen="2">is</d>
+    <e strLen="22">an xml sample document</e>
+  </alpha>
+</result>
diff --git a/tests/fn_parse_xml/test1.xsl b/tests/fn_parse_xml/test1.xsl
new file mode 100644
index 00000000..9fdb6234
--- /dev/null
+++ b/tests/fn_parse_xml/test1.xsl
@@ -0,0 +1,47 @@
+<?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 -->
+   
+    <!-- An XSLT stylesheet test, for the XPath 3.1 fn:parse-xml() function.
+         The XPath function fn:parse-xml's example, as used within this
+         stylesheet is borrowed from XPath 3.1 F&O spec. -->                
+                
+    <xsl:output method="xml" indent="yes"/>
+    
+    <!-- The XML document string value, passed to fn:parse-xml 
+         function call within below mentioned xsl:variable 
+         declaration is following (with XML special characters 
+         escaped within function call fn:parse-xml's argument, 
+         according to XML conventions),
+         
+         <alpha>abcd</alpha> 
+    -->
+    <xsl:variable name="xmlDocNode" select="parse-xml('&lt;alpha&gt;abcd&lt;/alpha&gt;')"/>
+        
+    <xsl:template match="/">
+       <result>
+          <xsl:copy-of select="$xmlDocNode"/>
+       </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_parse_xml/test2.xsl b/tests/fn_parse_xml/test2.xsl
new file mode 100644
index 00000000..3dcbd6e1
--- /dev/null
+++ b/tests/fn_parse_xml/test2.xsl
@@ -0,0 +1,76 @@
+<?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 -->
+   
+    <!-- An XSLT stylesheet test, for the XPath 3.1 fn:parse-xml() 
+         function.
+         
+         Within this stylesheet, we parse an XML document string value
+         with function call fn:parse-xml, and do an XSLT transformation
+         on the XML document node returned by the function call 
+         fn:parse-xml. -->                
+                
+    <xsl:output method="xml" indent="yes"/>
+    
+    <!-- The XML document string value, passed to fn:parse-xml 
+         function call within below mentioned xsl:variable 
+         declaration is following (with XML special characters 
+         escaped within function call fn:parse-xml's argument, 
+         according to XML conventions),
+                  
+         <alpha>
+            <a>hello</a>
+            <b>world</b>
+            <c>this</c>
+            <d>is</d>
+            <e>an xml sample document</e>
+         </alpha>          
+    -->
+    <xsl:variable name="xmlDocNode" select="parse-xml('&lt;alpha&gt;
+                                                          &lt;a&gt;hello&lt;/a&gt;
+                                                          &lt;b&gt;world&lt;/b&gt;
+                                                          &lt;c&gt;this&lt;/c&gt;
+                                                          &lt;d&gt;is&lt;/d&gt;
+                                                          &lt;e&gt;an xml sample document&lt;/e&gt;
+                                                       &lt;/alpha&gt;')"/>
+        
+    <xsl:template match="/">
+       <result>
+          <xsl:apply-templates select="$xmlDocNode/alpha"/>
+       </result>
+    </xsl:template>
+    
+    <xsl:template match="alpha">
+      <alpha>
+         <xsl:apply-templates select="*" mode="m1"/>
+      </alpha>
+    </xsl:template>
+    
+    <xsl:template match="*" mode="m1">
+       <xsl:element name="{name()}">
+          <xsl:attribute name="strLen" select="string-length(.)"/>
+          <xsl:copy-of select="node()"/>
+       </xsl:element>
+    </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/FnParseXmlTests.java b/tests/org/apache/xalan/xpath3/FnParseXmlTests.java
new file mode 100644
index 00000000..8fa55501
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/FnParseXmlTests.java
@@ -0,0 +1,72 @@
+/*
+ * 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:parse-xml test cases.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FnParseXmlTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+                                                                                                          + "fn_parse_xml/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX 
+                                                                                                          + "fn_parse_xml/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 xslFnParseXmlTest1() {
+        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 xslFnParseXmlTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index d6e50b02..d874999c 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -29,6 +29,7 @@ import org.apache.xalan.xpath3.FnFoldRightTests;
 import org.apache.xalan.xpath3.FnForEachPairTests;
 import org.apache.xalan.xpath3.FnForEachTests;
 import org.apache.xalan.xpath3.FnIndexOfTests;
+import org.apache.xalan.xpath3.FnParseXmlTests;
 import org.apache.xalan.xpath3.FnSortTests;
 import org.apache.xalan.xpath3.FnStringJoinTests;
 import org.apache.xalan.xpath3.FnStringToCodepointsTests;
@@ -84,7 +85,7 @@ 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 })
+                SequenceFunctionTests.class, FnParseXmlTests.class })
 public class AllXsl3Tests {
 
 }


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