You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2025/03/23 10:55:06 UTC
(xalan-java) branch xalan-j_xslt3.0_mvn updated: implementation improvements to xalan-j xsl 3 xsl:template instruction having 'match' attribute for match patterns '.'/'.[...] when xsl:template instruction has one or both of mode and priority attributes, and few new working test cases
This is an automated email from the ASF dual-hosted git repository.
mukulg pushed a commit to branch xalan-j_xslt3.0_mvn
in repository https://gitbox.apache.org/repos/asf/xalan-java.git
The following commit(s) were added to refs/heads/xalan-j_xslt3.0_mvn by this push:
new be75e1e30 implementation improvements to xalan-j xsl 3 xsl:template instruction having 'match' attribute for match patterns '.'/'.[...] when xsl:template instruction has one or both of mode and priority attributes, and few new working test cases
be75e1e30 is described below
commit be75e1e30cf95fd2ad69a04d22558d7af7648ae7
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sun Mar 23 16:24:52 2025 +0530
implementation improvements to xalan-j xsl 3 xsl:template instruction having 'match' attribute for match patterns '.'/'.[...] when xsl:template instruction has one or both of mode and priority attributes, and few new working test cases
---
README | 6 +-
.../apache/xalan/templates/ElemApplyTemplates.java | 270 ++++++++++++++++-----
.../org/apache/xalan/templates/TemplateList.java | 34 +--
.../org/apache/xpath/compiler/XPathParser.java | 2 -
.../apache/xalan/tests/xslt3/XslTemplateTests.java | 22 +-
src/test/resources/xsl_template/gold/test19.out | 9 +
src/test/resources/xsl_template/gold/test20.out | 9 +
src/test/resources/xsl_template/test19.xsl | 54 +++++
src/test/resources/xsl_template/test20.xsl | 54 +++++
9 files changed, 375 insertions(+), 85 deletions(-)
diff --git a/README b/README
index 3d91757aa..00d124ab3 100644
--- a/README
+++ b/README
@@ -17,7 +17,7 @@
Copyright 1999-2025 The Apache Software Foundation
-Document last modified : 2025-03-20
+Document last modified : 2025-03-23
Authors:
Gary Gregory <gg...@apache.org>
@@ -59,11 +59,11 @@ This produces Maven build output with trailing information like following:
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.apache.xalan.tests.main.AllXsl3Tests
-[INFO] Tests run: 950, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 19.383 s - in org.apache.xalan.tests.main.AllXsl3Tests
+[INFO] Tests run: 952, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 46.826 s - in org.apache.xalan.tests.main.AllXsl3Tests
[INFO]
[INFO] Results:
[INFO]
-[INFO] Tests run: 950, Failures: 0, Errors: 0, Skipped: 0
+[INFO] Tests run: 952, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
diff --git a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
index f475aaf7f..87f260e82 100644
--- a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
+++ b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
@@ -20,6 +20,7 @@
*/
package org.apache.xalan.templates;
+import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
@@ -647,15 +648,15 @@ public class ElemApplyTemplates extends ElemCallTemplate
Hashtable templateListHashTable = tl.getPatternTable();
Set hashTableEntrySet = templateListHashTable.entrySet();
- Iterator iter = hashTableEntrySet.iterator();
+ // Iterator iter = hashTableEntrySet.iterator();
for (int idx = 0; idx < resultSeq.size(); idx++) {
XObject xObj = resultSeq.item(idx);
- executeXslTransformAtomicValue(transformer, xctxt, xObj, iter, xslTemplateInvokeMode);
+ executeXslTransformAtomicValue(transformer, xctxt, xObj, hashTableEntrySet, xslTemplateInvokeMode);
// Reset an iterator object instance
- iter = hashTableEntrySet.iterator();
+ // iter = hashTableEntrySet.iterator();
}
}
@@ -664,109 +665,177 @@ public class ElemApplyTemplates extends ElemCallTemplate
* transformation for one XDM atomic value.
*/
private void executeXslTransformAtomicValue(TransformerImpl transformer, final XPathContext xctxt,
- XObject xObj, QName xslTemplateInvokeMode) throws TransformerException {
+ XObject contextItem, QName xslTemplateInvokeMode) throws TransformerException {
final StylesheetRoot sroot = transformer.getStylesheet();
final TemplateList tl = sroot.getTemplateListComposed();
Hashtable templateListHashTable = tl.getPatternTable();
Set hashTableEntrySet = templateListHashTable.entrySet();
- Iterator iter = hashTableEntrySet.iterator();
+ // Iterator iter = hashTableEntrySet.iterator();
- executeXslTransformAtomicValue(transformer, xctxt, xObj, iter, xslTemplateInvokeMode);
+ executeXslTransformAtomicValue(transformer, xctxt, contextItem, hashTableEntrySet, xslTemplateInvokeMode);
// Recreate an iterator object instance
- iter = hashTableEntrySet.iterator();
+ //iter = hashTableEntrySet.iterator();
}
/**
* This method definition does, an XSL transform for one XDM atomic value.
*/
- private void executeXslTransformAtomicValue(TransformerImpl transformer, final XPathContext xctxt, XObject xObj,
- Iterator iter, QName xslTemplateInvokeMode) throws TransformerException {
+ private void executeXslTransformAtomicValue(TransformerImpl transformer, final XPathContext xctxt, XObject contextItem,
+ Set hashTableEntrySet, QName xslTemplateInvokeMode) throws TransformerException {
- ElemTemplate elemTemplate = null;
+ Iterator iter = hashTableEntrySet.iterator();
- SourceLocator srcLocator = xctxt.getSAXLocator();
+ ElemTemplate elemTemplate = null;
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
XObject prevCtxItem = xctxt.getXPath3ContextItem();
+ xctxt.setXPath3ContextItem(contextItem);
+
+ // A list of TemplateDefnPriorityPair object instances, is needed to sort
+ // ElemTemplate object instances by a numeric priority (if this priority
+ // is not specified within an XSL stylesheet, then its value is
+ // java double -Infinity which is the min value of java double as
+ // provided by jdk).
+ List<TemplateDefnPriorityPair> templateDefnPriorityPairList = new ArrayList<TemplateDefnPriorityPair>();
+
+ // This while loop finds an ElemTemplate object instance, that will be
+ // used to do an XSL transformation of an XPath data model atomic
+ // value (for e.g, xs:string, xs:integer etc) that has been passed as
+ // an argument to this method.
+
+ // An xsl:template instance selected for this purpose, is chosen on the
+ // basis of xsl:template's mode and priority. Programmatically, an
+ // xsl:template instance will always have priority (which will be
+ // java lang -Infinity double value if not specified within an
+ // XSL stylesheet, otherwise it'll be a valid xs:decimal finite number).
+ // Programmatically, an xsl:template's mode will be null when not
+ // specified with an XML attribute named 'mode', otherwise it'll be
+ // an XML QName non-null typed value.
+
+ boolean templateSelectedWithoutPriority = false;
+
while (iter.hasNext()) {
Entry<Object, Object> hashTableEntry = (Entry<Object, Object>)iter.next();
Object hashTableKeyObj = hashTableEntry.getKey();
TemplateSubPatternAssociation hashTableValueObj = (TemplateSubPatternAssociation)(hashTableEntry.getValue());
elemTemplate = hashTableValueObj.getTemplate();
- QName templateDefnMode = elemTemplate.getMode();
- boolean templateSelected = false;
+ QName templateDefnMode = elemTemplate.getMode();
+
if ((xslTemplateInvokeMode != null) && (templateDefnMode != null)) {
if (xslTemplateInvokeMode.equals(templateDefnMode)) {
- templateSelected = true;
+ templateSelectedWithoutPriority = true;
}
}
else if ((xslTemplateInvokeMode != null) && (templateDefnMode == null)) {
- templateSelected = false;
+ templateSelectedWithoutPriority = false;
}
else if ((xslTemplateInvokeMode == null) && (templateDefnMode != null)) {
- templateSelected = false;
+ templateSelectedWithoutPriority = false;
}
else {
- templateSelected = true;
+ templateSelectedWithoutPriority = true;
}
- String keyValueStr = (String)hashTableKeyObj;
- int index1 = keyValueStr.indexOf(Constants.XSL3_PATTERN_TABLE_DELIM);
- if (index1 >= 0) {
- keyValueStr = keyValueStr.substring(0, index1);
- }
+ if (!templateSelectedWithoutPriority) {
+ continue;
+ }
- if (templateSelected) {
- xctxt.setXPath3ContextItem(xObj);
+ String keyValueStr = (String)hashTableKeyObj;
+ String[] strArray1 = keyValueStr.split(Constants.XSL3_PATTERN_TABLE_DELIM);
+ if (keyValueStr.startsWith(".[") && (strArray1.length == 3)) {
+ String xslTemplatePriorityStr = strArray1[2];
+ String xpathStr = keyValueStr.substring(0, keyValueStr.indexOf(Constants.XSL3_PATTERN_TABLE_DELIM));
+ xpathStr = xpathStr.substring(2);
+ xpathStr = xpathStr.substring(0, xpathStr.length() - 1);
- if (keyValueStr.startsWith(".[")) {
- String xpathStr = keyValueStr.substring(2);
- xpathStr = xpathStr.substring(0, xpathStr.length() - 1);
- XPath xpath = new XPath(xpathStr, srcLocator, xctxt.getNamespaceContext(),
- XPath.SELECT, null);
- XObject xpathEvalResult = xpath.execute(xctxt, DTM.NULL, xctxt.getNamespaceContext());
- boolean isSuccess = false;
- if (xpathEvalResult instanceof XBooleanStatic) {
- XBooleanStatic xBoolStatic = (XBooleanStatic)xpathEvalResult;
- isSuccess = xBoolStatic.bool();
- }
- else if (xpathEvalResult instanceof XBoolean) {
- XBoolean xBoolean = (XBoolean)xpathEvalResult;
- isSuccess = xBoolean.bool();
- }
- else if (xpathEvalResult instanceof XSBoolean) {
- XSBoolean xsBoolean = (XSBoolean)xpathEvalResult;
- isSuccess = xsBoolean.bool();
- }
-
- if (isSuccess) {
- for (ElemTemplateElement t = elemTemplate.m_firstChild;
- t != null; t = t.m_nextSibling) {
- xctxt.setSAXLocator(t);
- transformer.pushElemTemplateElement(t);
- t.execute(transformer);
- transformer.popElemTemplateElement();
- }
-
- break;
- }
+ XPath xpath = new XPath(xpathStr, srcLocator, xctxt.getNamespaceContext(),
+ XPath.SELECT, null);
+ XObject xpathEvalResult = xpath.execute(xctxt, DTM.NULL, xctxt.getNamespaceContext());
+ if (xpathEvalResult instanceof XBooleanStatic) {
+ XBooleanStatic xBoolStatic = (XBooleanStatic)xpathEvalResult;
+ templateSelectedWithoutPriority = xBoolStatic.bool();
}
- else if (".".equals(keyValueStr)) {
- for (ElemTemplateElement t = elemTemplate.m_firstChild;
- t != null; t = t.m_nextSibling) {
- xctxt.setSAXLocator(t);
- transformer.pushElemTemplateElement(t);
- t.execute(transformer);
- transformer.popElemTemplateElement();
- }
-
- break;
+ else if (xpathEvalResult instanceof XBoolean) {
+ XBoolean xBoolean = (XBoolean)xpathEvalResult;
+ templateSelectedWithoutPriority = xBoolean.bool();
+ }
+ else if (xpathEvalResult instanceof XSBoolean) {
+ XSBoolean xsBoolean = (XSBoolean)xpathEvalResult;
+ templateSelectedWithoutPriority = xsBoolean.bool();
+ }
+
+ if (templateSelectedWithoutPriority) {
+ TemplateDefnPriorityPair templateDefnPriorityPair = new TemplateDefnPriorityPair(keyValueStr, elemTemplate,
+ (Double.valueOf(xslTemplatePriorityStr)).doubleValue());
+ templateDefnPriorityPairList.add(templateDefnPriorityPair);
}
}
+
+ } // while (iter.hasNext())
+
+ if (templateDefnPriorityPairList.size() == 0) {
+ // Reset iterator
+ iter = hashTableEntrySet.iterator();
+
+ while (iter.hasNext()) {
+ Entry<Object, Object> hashTableEntry = (Entry<Object, Object>)iter.next();
+ Object hashTableKeyObj = hashTableEntry.getKey();
+ TemplateSubPatternAssociation hashTableValueObj = (TemplateSubPatternAssociation)(hashTableEntry.getValue());
+ elemTemplate = hashTableValueObj.getTemplate();
+
+ QName templateDefnMode = elemTemplate.getMode();
+
+ if ((xslTemplateInvokeMode != null) && (templateDefnMode != null)) {
+ if (xslTemplateInvokeMode.equals(templateDefnMode)) {
+ templateSelectedWithoutPriority = true;
+ }
+ }
+ else if ((xslTemplateInvokeMode != null) && (templateDefnMode == null)) {
+ templateSelectedWithoutPriority = false;
+ }
+ else if ((xslTemplateInvokeMode == null) && (templateDefnMode != null)) {
+ templateSelectedWithoutPriority = false;
+ }
+ else {
+ templateSelectedWithoutPriority = true;
+ }
+
+ if (!templateSelectedWithoutPriority) {
+ continue;
+ }
+
+ String keyValueStr = (String)hashTableKeyObj;
+ String[] strArray1 = keyValueStr.split(Constants.XSL3_PATTERN_TABLE_DELIM);
+ if (".".equals(strArray1[0]) && (strArray1.length == 3)) {
+ String xslTemplatePriorityStr = strArray1[2];
+ TemplateDefnPriorityPair templateDefnPriorityPair = new TemplateDefnPriorityPair(keyValueStr, elemTemplate,
+ (Double.valueOf(xslTemplatePriorityStr)).doubleValue());
+ templateDefnPriorityPairList.add(templateDefnPriorityPair);
+
+ }
+
+ } // while (iter.hasNext())
+ }
+
+ templateDefnPriorityPairList.sort(null);
+
+ TemplateDefnPriorityPair templateDefnPriorityPair = templateDefnPriorityPairList.get(
+ templateDefnPriorityPairList.size() - 1);
+
+ elemTemplate = templateDefnPriorityPair.getElemTemplate();
+
+ for (ElemTemplateElement t = elemTemplate.m_firstChild;
+ t != null; t = t.m_nextSibling) {
+ xctxt.setSAXLocator(t);
+ transformer.pushElemTemplateElement(t);
+ t.execute(transformer);
+ transformer.popElemTemplateElement();
}
xctxt.setXPath3ContextItem(prevCtxItem);
@@ -803,5 +872,76 @@ public class ElemApplyTemplates extends ElemCallTemplate
return result;
}
+
+ /**
+ * A list containing objects of this class, is sortable in an ascending
+ * order by priority java's double value.
+ *
+ * An xsl:template definition's priority is defined to have xs:decimal
+ * data type, according to XSLT 3 spec.
+ */
+ class TemplateDefnPriorityPair implements Comparable<TemplateDefnPriorityPair> {
+
+ private String keyValueStr = null;
+
+ private ElemTemplate elemTemplate = null;
+
+ private double priority;
+
+ /**
+ * Default class constructor.
+ */
+ public TemplateDefnPriorityPair() {
+ // NO OP
+ }
+
+ /**
+ * Class constructor.
+ */
+ public TemplateDefnPriorityPair(String keyValueStr, ElemTemplate elemTemplate, double priority) {
+ this.keyValueStr = keyValueStr;
+ this.elemTemplate = elemTemplate;
+ this.priority = priority;
+ }
+
+ public ElemTemplate getElemTemplate() {
+ return elemTemplate;
+ }
+
+ public void setElemTemplate(ElemTemplate elemTemplate) {
+ this.elemTemplate = elemTemplate;
+ }
+
+ public String getKeyValueStr() {
+ return keyValueStr;
+ }
+
+ public void setKeyValueStr(String keyValueStr) {
+ this.keyValueStr = keyValueStr;
+ }
+
+ public double getPriority() {
+ return priority;
+ }
+
+ public void setPriority(double priority) {
+ this.priority = priority;
+ }
+
+ @Override
+ public int compareTo(TemplateDefnPriorityPair obj1) {
+ int result = 0;
+
+ if (this.priority < obj1.getPriority()) {
+ result = -1;
+ }
+ else if (this.priority > obj1.getPriority()) {
+ result = 1;
+ }
+
+ return result;
+ }
+
+ }
}
diff --git a/src/main/java/org/apache/xalan/templates/TemplateList.java b/src/main/java/org/apache/xalan/templates/TemplateList.java
index 141f9ee6c..50f5ce81b 100644
--- a/src/main/java/org/apache/xalan/templates/TemplateList.java
+++ b/src/main/java/org/apache/xalan/templates/TemplateList.java
@@ -112,8 +112,6 @@ public class TemplateList implements java.io.Serializable
String xpathPatternStr = templateMatchXPath.getPatternString();
if (".".equals(xpathPatternStr) || xpathPatternStr.startsWith(".[")) {
insertPatternInTable(String.valueOf(xpathPatternStr), template);
-
- XslTransformSharedDatastore.templateMatchDotPatternPredicateStr = null;
}
else if (matchExpr instanceof StepPattern)
{
@@ -388,32 +386,40 @@ public class TemplateList implements java.io.Serializable
/**
* Add a template to the template list.
*
- * This method definition supports, XSLT 3.0 xsl:template match pattern
- * strings ".", .[...].
+ * This method definition supports XSLT 3 xsl:template pattern strings
+ * like ".", and .[...] (this is XPath pattern '.' followed by predicate
+ * that imposes a boolean filter condition on context value '.'. Only
+ * one predicate is supported here).
*
* @param pattern
* @param template
*/
- private void insertPatternInTable(String xpathMatchPatternStr, ElemTemplate template) {
+ private void insertPatternInTable(String pattern, ElemTemplate template) {
TemplateSubPatternAssociation association =
- new TemplateSubPatternAssociation(template, null, xpathMatchPatternStr);
+ new TemplateSubPatternAssociation(template, null, pattern);
+
+ String patternTableKeyStr = pattern;
QName templateModeQname = template.getMode();
+
String templateModeStr = null;
if (templateModeQname != null) {
templateModeStr = templateModeQname.toString();
}
+
if (templateModeStr != null) {
- /**
- * This allows us to store within an Hashtable m_patternTable object,
- * more than one xsl:template definition object instances having
- * same value of "match" attribute but with different template
- * definition mode names.
- */
- xpathMatchPatternStr = (xpathMatchPatternStr + Constants.XSL3_PATTERN_TABLE_DELIM + templateModeStr);
+ patternTableKeyStr = (patternTableKeyStr + Constants.XSL3_PATTERN_TABLE_DELIM + templateModeStr);
}
+ else {
+ patternTableKeyStr = (patternTableKeyStr + Constants.XSL3_PATTERN_TABLE_DELIM + "mode_unspecified");
+ }
+
+ double templatePriority = template.getPriority();
+ String templatePriorityStr = String.valueOf(templatePriority);
+
+ patternTableKeyStr = (patternTableKeyStr + Constants.XSL3_PATTERN_TABLE_DELIM + templatePriorityStr);
- m_patternTable.put(xpathMatchPatternStr, association);
+ m_patternTable.put(patternTableKeyStr, association);
}
/**
diff --git a/src/main/java/org/apache/xpath/compiler/XPathParser.java b/src/main/java/org/apache/xpath/compiler/XPathParser.java
index f7d90e4fd..0bceeb73c 100644
--- a/src/main/java/org/apache/xpath/compiler/XPathParser.java
+++ b/src/main/java/org/apache/xpath/compiler/XPathParser.java
@@ -4609,8 +4609,6 @@ public class XPathParser
nextToken();
}
}
-
- XslTransformSharedDatastore.templateMatchDotPatternPredicateStr = strBuff.toString();
}
}
else
diff --git a/src/test/java/org/apache/xalan/tests/xslt3/XslTemplateTests.java b/src/test/java/org/apache/xalan/tests/xslt3/XslTemplateTests.java
index a30cdf0aa..0bea647f9 100644
--- a/src/test/java/org/apache/xalan/tests/xslt3/XslTemplateTests.java
+++ b/src/test/java/org/apache/xalan/tests/xslt3/XslTemplateTests.java
@@ -23,7 +23,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
/**
- * XSLT test cases, to test xsl:template instruction.
+ * XSL 3 transformation test cases, to test xsl:template instruction.
*
* @author Mukul Gandhi <mu...@apache.org>
*
@@ -227,5 +227,25 @@ public class XslTemplateTests extends XSLTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xslTemplateTest19() {
+ 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 xslTemplateTest20() {
+ 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/src/test/resources/xsl_template/gold/test19.out b/src/test/resources/xsl_template/gold/test19.out
new file mode 100644
index 000000000..a852d2da6
--- /dev/null
+++ b/src/test/resources/xsl_template/gold/test19.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <n>Hello world, this text file is used for testing purpose</n>
+ <n>== Thanks for reading this</n>
+ <n>Many thanks</n>
+ <n>:: Thank you</n>
+ <n>== Your's sincerely</n>
+ <n>--</n>
+ <n>Apache Xalan</n>
+</result>
diff --git a/src/test/resources/xsl_template/gold/test20.out b/src/test/resources/xsl_template/gold/test20.out
new file mode 100644
index 000000000..c6410b488
--- /dev/null
+++ b/src/test/resources/xsl_template/gold/test20.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <m>Hello world, this text file is used for testing purpose</m>
+ <m>== Thanks for reading this</m>
+ <m>Many thanks</m>
+ <m>:: Thank you</m>
+ <m>== Your's sincerely</m>
+ <m>--</m>
+ <m>Apache Xalan</m>
+</result>
diff --git a/src/test/resources/xsl_template/test19.xsl b/src/test/resources/xsl_template/test19.xsl
new file mode 100644
index 000000000..657cfc9a1
--- /dev/null
+++ b/src/test/resources/xsl_template/test19.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"
+ exclude-result-prefixes="xs"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSL 3 stylesheet test case, to test xsl:template match
+ with pattern ".", and resolving which xsl:template to
+ use depending on priority of template.
+
+ This XSL stylesheet example's algorithm has been borrowed
+ from XSLT 3.0 spec.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:for-each select="unparsed-text-lines('input.txt')">
+ <xsl:variable name="item1" select="." as="xs:string"/>
+ <xsl:apply-templates select="$item1"/>
+ </xsl:for-each>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="." priority="2">
+ <m><xsl:value-of select="."/></m>
+ </xsl:template>
+
+ <xsl:template match="." priority="3">
+ <n><xsl:value-of select="."/></n>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/src/test/resources/xsl_template/test20.xsl b/src/test/resources/xsl_template/test20.xsl
new file mode 100644
index 000000000..2741b8656
--- /dev/null
+++ b/src/test/resources/xsl_template/test20.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"
+ exclude-result-prefixes="xs"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- An XSL 3 stylesheet test case, to test xsl:template match
+ with pattern ".", and resolving which xsl:template to
+ use depending on priority of template.
+
+ This XSL stylesheet example's algorithm has been borrowed
+ from XSLT 3.0 spec.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:for-each select="unparsed-text-lines('input.txt')">
+ <xsl:variable name="item1" select="." as="xs:string"/>
+ <xsl:apply-templates select="$item1"/>
+ </xsl:for-each>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="." priority="3">
+ <m><xsl:value-of select="."/></m>
+ </xsl:template>
+
+ <xsl:template match="." priority="2">
+ <n><xsl:value-of select="."/></n>
+ </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>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org