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/10/24 11:55:01 UTC
(xalan-java) branch xalan-j_xslt3.0_mvn updated: committing xalan-j xslt 3.0 implementation improvements for xsl:mode instruction
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 6ecee35e7 committing xalan-j xslt 3.0 implementation improvements for xsl:mode instruction
6ecee35e7 is described below
commit 6ecee35e7c1c7d7346af6406268a17808aa8aa4e
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Fri Oct 24 17:24:27 2025 +0530
committing xalan-j xslt 3.0 implementation improvements for xsl:mode instruction
---
.../apache/xalan/processor/XSLTAttributeDef.java | 28 +++-
.../org/apache/xalan/processor/XSLTSchema.java | 5 +
.../java/org/apache/xalan/templates/Constants.java | 4 +
.../apache/xalan/templates/ElemApplyTemplates.java | 114 ++++++++-----
.../java/org/apache/xalan/templates/ElemMode.java | 38 ++++-
.../org/apache/xalan/templates/Stylesheet.java | 176 ++++++++++++++++++---
.../org/apache/xalan/templates/StylesheetRoot.java | 4 +-
.../org/apache/xalan/templates/TemplateList.java | 23 ++-
.../apache/xalan/transformer/TransformerImpl.java | 49 +++---
.../w3c/xslt3/misc/XslBuiltInTemplateTests.java | 8 -
10 files changed, 344 insertions(+), 105 deletions(-)
diff --git a/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java b/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java
index 12df77400..d4c08c7ce 100644
--- a/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java
+++ b/src/main/java/org/apache/xalan/processor/XSLTAttributeDef.java
@@ -33,6 +33,7 @@ import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.templates.AVT;
import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemApplyTemplates;
import org.apache.xalan.templates.ElemForEachGroup;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.xslt.util.StringUtil;
@@ -1040,14 +1041,27 @@ public class XSLTAttributeDef
return null;
}
}
+ else if ((owner instanceof ElemApplyTemplates) && (Constants.ATTRNAME_MODE).equals(name) &&
+ (Constants.ATTRVAL_DEFAULT_PREFIX).equals(value)) {
+ // We use, non-standard namespace for this QName object, because
+ // string #default is not a valid QName string.
+ qname = new QName("http://xml.apache.org/xalan", "default", true);
+ }
+ else if ((owner instanceof ElemApplyTemplates) && (Constants.ATTRNAME_MODE).equals(name) &&
+ (Constants.ATTRVAL_UNNAMED_PREFIX).equals(value)) {
+ // We use, non-standard namespace for this QName object, because
+ // string #unnamed is not a valid QName string.
+ qname = new QName("http://xml.apache.org/xalan", "unnamed", true);
+ }
+ else if ((owner instanceof ElemApplyTemplates) && (Constants.ATTRNAME_MODE).equals(name) &&
+ (Constants.ATTRVAL_CURRENT_PREFIX).equals(value)) {
+ // We use, non-standard namespace for this QName object, because
+ // string #current is not a valid QName string.
+ qname = new QName("http://xml.apache.org/xalan", "current", true);
+ }
else {
- if ((Constants.ATTRNAME_MODE).equals(name) && (Constants.ATTRVAL_DEFAULT_PREFIX).equals(value)) {
- qname = new QName("http://xml.apache.org/xalan", "default", true);
- }
- else {
- qname = new QName(value, handler, true);
- }
- }
+ qname = new QName(value, handler, true);
+ }
return qname;
}
diff --git a/src/main/java/org/apache/xalan/processor/XSLTSchema.java b/src/main/java/org/apache/xalan/processor/XSLTSchema.java
index 364d23866..e37c2acfe 100644
--- a/src/main/java/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/main/java/org/apache/xalan/processor/XSLTSchema.java
@@ -180,6 +180,10 @@ public class XSLTSchema extends XSLTElementDef
XSLTAttributeDef.T_YESNO, false, false, XSLTAttributeDef.ERROR);
XSLTAttributeDef mediaTypeAttr = new XSLTAttributeDef(null, "media-type",
XSLTAttributeDef.T_CDATA, false, false, XSLTAttributeDef.ERROR);
+
+ // xsl:stylesheet, xsl:transform
+ XSLTAttributeDef defaultModeAttr = new XSLTAttributeDef(null, "default-mode",
+ XSLTAttributeDef.T_QNAME, false, false, XSLTAttributeDef.ERROR);
// Required.
@@ -1366,6 +1370,7 @@ public class XSLTSchema extends XSLTElementDef
versionAttrRequired,
xpathDefaultNamespaceAttrOpt,
expandTextAttrOpt,
+ defaultModeAttr,
spaceAttr }, new ProcessorStylesheetElement(), /* ContentHandler */
null /* class object */,
true, -1, false);
diff --git a/src/main/java/org/apache/xalan/templates/Constants.java b/src/main/java/org/apache/xalan/templates/Constants.java
index f3fe074a9..cddd98285 100644
--- a/src/main/java/org/apache/xalan/templates/Constants.java
+++ b/src/main/java/org/apache/xalan/templates/Constants.java
@@ -450,6 +450,10 @@ public class Constants extends org.apache.xml.utils.Constants
/** For Stylesheet-prefix and result-prefix in xsl:namespace-alias */
public static final String ATTRVAL_DEFAULT_PREFIX = "#default";
+ public static final String ATTRVAL_UNNAMED_PREFIX = "#unnamed";
+
+ public static final String ATTRVAL_CURRENT_PREFIX = "#current";
+
public static final String ATTRVAL_ALL_PREFIX = "#all";
/** Integer equivalents for above */
diff --git a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
index 0b7ad88e3..9458159a0 100644
--- a/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
+++ b/src/main/java/org/apache/xalan/templates/ElemApplyTemplates.java
@@ -28,6 +28,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
+import javax.xml.transform.ErrorListener;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
@@ -38,7 +39,6 @@ import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMCursorIterator;
import org.apache.xml.serializer.SerializationHandler;
-import org.apache.xml.utils.DefaultErrorHandler;
import org.apache.xml.utils.IntStack;
import org.apache.xml.utils.QName;
import org.apache.xpath.Expression;
@@ -559,9 +559,40 @@ public class ElemApplyTemplates extends ElemCallTemplate
IntStack currentNodes = xctxt.getCurrentNodeStack();
- IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();
-
- int child;
+ IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();
+
+ QName mode = transformer.getMode();
+
+ QName qnameCurrent = new QName("http://xml.apache.org/xalan", "current", true);
+ QName qnameUnnamed = new QName("http://xml.apache.org/xalan", "unnamed", true);
+ if (qnameCurrent.equals(mode)) {
+ mode = transformer.getCurrentMode();
+ }
+ else if (qnameUnnamed.equals(mode)) {
+ mode = null;
+ }
+
+ ElemMode elemMode = sroot.getElemMode(mode);
+
+ String onNoMatchStr = null;
+ String xslOnMultipleMatchStr = null;
+ boolean xslWarningOnMultipleMatch = false;
+
+ if (elemMode != null) {
+ xslOnMultipleMatchStr = elemMode.getOnMultipleMatch();
+ if (xslOnMultipleMatchStr != null) {
+ if (!((Constants.ATTRVAL_USE_LAST).equals(xslOnMultipleMatchStr) || (Constants.ATTRVAL_FAIL).equals(xslOnMultipleMatchStr))) {
+ throw new TransformerException("XTTE0505 : An xsl:mode instruction's \"on-multiple-match\" attribute has in-correct "
+ + "value '" + xslOnMultipleMatchStr + "'.", srcLocator);
+ }
+ }
+
+ xslWarningOnMultipleMatch = elemMode.isWarningOnMultipleMatch();
+
+ onNoMatchStr = elemMode.getOnNoMatch();
+ }
+
+ int child;
while (DTM.NULL != (child = sourceNodes.nextNode()))
{
currentNodes.setTop(child);
@@ -575,24 +606,6 @@ public class ElemApplyTemplates extends ElemCallTemplate
final int exNodeType = dtm.getExpandedTypeID(child);
final int nodeType = dtm.getNodeType(child);
-
- final QName mode = transformer.getMode();
-
- ElemMode elemMode = sroot.getElemMode(mode);
-
- String xslOnMultipleMatchStr = null;
- boolean xslWarningOnMultipleMatch = false;
- if (elemMode != null) {
- xslOnMultipleMatchStr = elemMode.getOnMultipleMatch();
- if (xslOnMultipleMatchStr != null) {
- if (!((Constants.ATTRVAL_USE_LAST).equals(xslOnMultipleMatchStr) || (Constants.ATTRVAL_FAIL).equals(xslOnMultipleMatchStr))) {
- throw new TransformerException("XTTE0505 : An xsl:mode instruction's \"on-multiple-match\" attribute has in-correct "
- + "value '" + xslOnMultipleMatchStr + "'.", srcLocator);
- }
- }
-
- xslWarningOnMultipleMatch = elemMode.isWarningOnMultipleMatch();
- }
ElemTemplate template = tl.getTemplateFast(xctxt, child, exNodeType, mode, -1, true, dtm,
xslOnMultipleMatchStr, xslWarningOnMultipleMatch);
@@ -605,9 +618,14 @@ public class ElemApplyTemplates extends ElemCallTemplate
case DTM.DOCUMENT_FRAGMENT_NODE :
case DTM.ELEMENT_NODE :
if (elemMode != null) {
- String elemName = dtm.getNodeName(child);
- String onNoMatchStr = elemMode.getOnNoMatch();
- if (onNoMatchStr != null) {
+ String elemName = dtm.getNodeName(child);
+ if (onNoMatchStr != null) {
+ /**
+ * Finding an XSL stylesheet built-in template rule, when
+ * xsl:mode instruction specifies an attribute 'on-no-match',
+ * with an allowed non-null value.
+ */
+
if ((Constants.ATTRVAL_TEXT_ONLY_COPY).equals(onNoMatchStr)) {
template = sroot.getTextOnlyCopyRule(elemMode.getName(), nodeType);
}
@@ -624,7 +642,7 @@ public class ElemApplyTemplates extends ElemCallTemplate
template = sroot.getShallowSkipRule(elemMode.getName(), nodeType);
}
else if ((Constants.ATTRVAL_FAIL).equals(onNoMatchStr)) {
- String errMesg = "XTDE0555 : An xsl:template declaration could not be found to process an XML element node";
+ String errMesg = "XTDE0555 : An xsl:template declaration could not be located to process an XML element node";
if (elemName != null) {
errMesg = (errMesg + " '" + elemName + "'.");
}
@@ -639,23 +657,35 @@ public class ElemApplyTemplates extends ElemCallTemplate
+ "value '" + onNoMatchStr + "'.", srcLocator);
}
}
- else {
- if (elemMode.isWarningOnNoMatch()) {
- int errLineNo = srcLocator.getLineNumber();
- if (errLineNo != 0) {
- DefaultErrorHandler errorListener = new DefaultErrorHandler();
- String errMesg = "Warning : An xsl:template declaration could not be found to process an XML element node";
- if (elemName != null) {
- errMesg = (errMesg + " '" + elemName + "'.");
- }
- else {
- errMesg = (errMesg + ".");
- }
- errorListener.warning(new TransformerException(errMesg, srcLocator));
+
+ if (elemMode.isWarningOnNoMatch()) {
+ /**
+ * Emitting an XSL stylesheet processing warning, when xsl:mode
+ * instruction specifies an attribute 'warning-on-no-match' with
+ * value true.
+ */
+
+ int errLineNo = srcLocator.getLineNumber();
+ if (errLineNo != 0) {
+ ErrorListener errorListener = xctxt.getErrorListener();
+ String errMesg = "Warning : An xsl:template declaration could not be located to process an XML element node";
+ if (elemName != null) {
+ errMesg = (errMesg + " '" + elemName + "'.");
+ }
+ else {
+ errMesg = (errMesg + ".");
}
+
+ errorListener.warning(new TransformerException(errMesg, srcLocator));
}
-
- template = sroot.getDefaultRule();
+ }
+
+ if ((Constants.ATTRVAL_TEXT_ONLY_COPY).equals(onNoMatchStr)) {
+ transformer.pushPairCurrentMatched(template, child);
+ transformer.setCurrentElement(template);
+ dtm.dispatchCharactersEvents(child, rth, false);
+ transformer.popCurrentMatched();
+ continue;
}
}
else {
@@ -669,7 +699,7 @@ public class ElemApplyTemplates extends ElemCallTemplate
transformer.pushPairCurrentMatched(sroot.getDefaultTextRule(), child);
transformer.setCurrentElement(sroot.getDefaultTextRule());
dtm.dispatchCharactersEvents(child, rth, false);
- transformer.popCurrentMatched();
+ transformer.popCurrentMatched();
continue;
case DTM.DOCUMENT_NODE :
template = sroot.getDefaultRootRule();
diff --git a/src/main/java/org/apache/xalan/templates/ElemMode.java b/src/main/java/org/apache/xalan/templates/ElemMode.java
index 58e677529..11100ddad 100644
--- a/src/main/java/org/apache/xalan/templates/ElemMode.java
+++ b/src/main/java/org/apache/xalan/templates/ElemMode.java
@@ -88,23 +88,45 @@ public class ElemMode extends ElemTemplateElement
/**
* An xsl:mode element's 'on-no-match' attribute.
+ *
+ * This has default value "text-only-copy", which may be
+ * overridden by XSL stylesheet's xsl:mode declaration.
*/
- private String m_onNoMatch = null;
+ private String m_onNoMatch = Constants.ATTRVAL_TEXT_ONLY_COPY;
/**
* An xsl:mode element's 'on-multiple-match' attribute.
+ *
+ * This has default value "use-last", which may be overridden
+ * by XSL stylesheet's xsl:mode declaration.
*/
- private String m_onMultipleMatch = null;
+ private String m_onMultipleMatch = Constants.ATTRVAL_USE_LAST;
/**
* An xsl:mode element's 'warning-on-no-match' attribute.
+ *
+ * Xalan's default value for this attribute is false.
*/
private boolean m_warningOnNoMatch = false;
+ /**
+ * This has boolean value true, if xsl:mode instruction's attribute
+ * 'warning-on-no-match' is declared within an XSL stylesheet.
+ */
+ private boolean m_warningOnNoMatchDeclared = false;
+
/**
* An xsl:mode element's 'warning-on-multiple-match' attribute.
+ *
+ * Xalan's default value for this attribute is false.
*/
private boolean m_warningOnMultipleMatch = false;
+
+ /**
+ * This has boolean value true, if xsl:mode instruction's attribute
+ * 'warning-on-multiple-match' is declared within an XSL stylesheet.
+ */
+ private boolean m_warningOnMultipleMatchDeclared = false;
/**
* Set the "name" attribute.
@@ -180,6 +202,12 @@ public class ElemMode extends ElemTemplateElement
*/
public void setWarningOnNoMatch(boolean warningOnNoMatch) {
this.m_warningOnNoMatch = warningOnNoMatch;
+
+ m_warningOnNoMatchDeclared = true;
+ }
+
+ public boolean isWarningOnNoMatchDeclared() {
+ return m_warningOnNoMatchDeclared;
}
/**
@@ -198,6 +226,12 @@ public class ElemMode extends ElemTemplateElement
*/
public void setWarningOnMultipleMatch(boolean warningOnMultipleMatch) {
this.m_warningOnMultipleMatch = warningOnMultipleMatch;
+
+ m_warningOnMultipleMatchDeclared = true;
+ }
+
+ public boolean isWarningOnMultipleMatchDeclared() {
+ return m_warningOnMultipleMatchDeclared;
}
/**
diff --git a/src/main/java/org/apache/xalan/templates/Stylesheet.java b/src/main/java/org/apache/xalan/templates/Stylesheet.java
index 85b3753cc..a0d5de7c2 100644
--- a/src/main/java/org/apache/xalan/templates/Stylesheet.java
+++ b/src/main/java/org/apache/xalan/templates/Stylesheet.java
@@ -407,6 +407,30 @@ public class Stylesheet extends ElemTemplateElement implements java.io.Serializa
public boolean getExpandText() {
return m_expand_text;
}
+
+ /**
+ * An xsl:stylesheet element's 'default-mode' attribute.
+ */
+ private QName m_xsl_default_mode = null;
+
+ /**
+ * Set the value of "default-mode" attribute.
+ *
+ * @param v Value of the "default-mode" attribute
+ */
+ public void setDefaultMode(QName modeName)
+ {
+ m_xsl_default_mode = modeName;
+ }
+
+ /**
+ * Get the value of "default-mode" attribute.
+ *
+ * @return The value of "default-mode" attribute
+ */
+ public QName getDefaultMode() {
+ return m_xsl_default_mode;
+ }
/**
* The "version" property.
@@ -1090,9 +1114,10 @@ public class Stylesheet extends ElemTemplateElement implements java.io.Serializa
/**
* An ElemMode object instance, referring to the default
- * mode, that doesn't have an attribute 'name'.
+ * mode, for xsl:mode instruction that doesn't have an
+ * attribute 'name'.
*/
- private ElemMode m_defaultMode;
+ private ElemMode m_defaultElemMode;
/**
* Set an "xsl:mode" property.
@@ -1111,25 +1136,130 @@ public class Stylesheet extends ElemTemplateElement implements java.io.Serializa
ElemMode elemModePrev = m_modeList.getElemMode(modeName);
if (elemModePrev == null) {
+ elemMode.setStylesheet(this);
m_modeList.setElemMode(elemMode);
}
else {
- throw new TransformerException("XTTE0505 : An XSL stylesheet has more than one xsl:mode declaration "
- + "with name '" + modeName.toString() + "'.", elemMode);
+ String modeNameStr = modeName.toString();
+
+ String prevOnNoMatchDeclStr = elemModePrev.getOnNoMatch();
+ String prevOnMultipleMatchStr = elemModePrev.getOnMultipleMatch();
+ boolean prevWarningOnNoMatch = elemModePrev.isWarningOnNoMatch();
+ boolean prevWarningOnMultipleMatch = elemModePrev.isWarningOnMultipleMatch();
+
+ boolean prevWarningOnNoMatchDeclared = elemModePrev.isWarningOnNoMatchDeclared();
+ boolean prevWarningOnMultipleMatchDeclared = elemModePrev.isWarningOnMultipleMatchDeclared();
+
+ String onNoMatchDeclStr = elemMode.getOnNoMatch();
+ String onMultipleMatchStr = elemMode.getOnMultipleMatch();
+ boolean warningOnNoMatch = elemMode.isWarningOnNoMatch();
+ boolean warningOnMultipleMatch = elemMode.isWarningOnMultipleMatch();
+
+ boolean warningOnNoMatchDeclared = elemMode.isWarningOnNoMatchDeclared();
+ boolean warningOnMultipleMatchDeclared = elemMode.isWarningOnMultipleMatchDeclared();
+
+ if ((prevOnNoMatchDeclStr != null) && (onNoMatchDeclStr != null)
+ && !onNoMatchDeclStr.equals(prevOnNoMatchDeclStr)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration with "
+ + "name '" + modeNameStr + "', that have conflicting "
+ + "values for \"xsl:mode\" attribute 'on-no-match'.");
+ }
+ else if ((prevOnNoMatchDeclStr != null) && (onNoMatchDeclStr == null)) {
+ elemMode.setOnNoMatch(prevOnNoMatchDeclStr);
+ }
+
+ if ((prevOnMultipleMatchStr != null) && (onMultipleMatchStr != null)
+ && onMultipleMatchStr.equals(prevOnMultipleMatchStr)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration with "
+ + "name '" + modeNameStr + "', that have conflicting "
+ + "values for \"xsl:mode\" attribute 'on-multiple-match'.");
+ }
+ else if ((prevOnMultipleMatchStr != null) && (onMultipleMatchStr == null)) {
+ elemMode.setOnMultipleMatch(prevOnMultipleMatchStr);
+ }
+
+ if (prevWarningOnNoMatchDeclared && warningOnNoMatchDeclared && (prevWarningOnNoMatch != warningOnNoMatch)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration with "
+ + "name '" + modeNameStr + "', that have conflicting "
+ + "values for \"xsl:mode\" attribute 'warning-on-no-match'.");
+ }
+ else if (prevWarningOnNoMatchDeclared) {
+ elemMode.setWarningOnNoMatch(prevWarningOnNoMatch);
+ }
+
+ if (prevWarningOnMultipleMatchDeclared && warningOnMultipleMatchDeclared && (prevWarningOnMultipleMatch != warningOnMultipleMatch)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration with "
+ + "name '" + modeNameStr + "', that have conflicting "
+ + "values for \"xsl:mode\" attribute 'warning-on-multiple-match'.");
+ }
+ else if (prevWarningOnMultipleMatchDeclared) {
+ elemMode.setWarningOnMultipleMatch(prevWarningOnMultipleMatch);
+ }
+
+ elemMode.setStylesheet(this);
+ m_modeList.setElemMode(elemMode);
}
}
else {
- if (m_defaultMode == null) {
- m_defaultMode = elemMode;
+ if (m_defaultElemMode == null) {
+ elemMode.setStylesheet(this);
+ m_defaultElemMode = elemMode;
}
else {
- throw new TransformerException("XTTE0505 : An XSL stylesheet cannot have more than one "
- + "xsl:mode declaration for default mode (i.e, xsl:mode "
- + "declaration without 'name' attribute).", elemMode);
+ ElemMode elemModePrev = m_defaultElemMode;
+
+ String prevOnNoMatchDeclStr = elemModePrev.getOnNoMatch();
+ String prevOnMultipleMatchStr = elemModePrev.getOnMultipleMatch();
+ boolean prevWarningOnNoMatch = elemModePrev.isWarningOnNoMatch();
+ boolean prevWarningOnMultipleMatch = elemModePrev.isWarningOnMultipleMatch();
+
+ boolean prevWarningOnNoMatchDeclared = elemModePrev.isWarningOnNoMatchDeclared();
+ boolean prevWarningOnMultipleMatchDeclared = elemModePrev.isWarningOnMultipleMatchDeclared();
+
+ String onNoMatchDeclStr = elemMode.getOnNoMatch();
+ String onMultipleMatchStr = elemMode.getOnMultipleMatch();
+ boolean warningOnNoMatch = elemMode.isWarningOnNoMatch();
+ boolean warningOnMultipleMatch = elemMode.isWarningOnMultipleMatch();
+
+ boolean warningOnNoMatchDeclared = elemMode.isWarningOnNoMatchDeclared();
+ boolean warningOnMultipleMatchDeclared = elemMode.isWarningOnMultipleMatchDeclared();
+
+ if ((prevOnNoMatchDeclStr != null) && (onNoMatchDeclStr != null)
+ && !onNoMatchDeclStr.equals(prevOnNoMatchDeclStr)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration for an unnamed mode, that "
+ + "have conflicting values for \"xsl:mode\" "
+ + "attribute 'on-no-match'.");
+ }
+ else if ((prevOnNoMatchDeclStr != null) && (onNoMatchDeclStr == null)) {
+ elemMode.setOnNoMatch(prevOnNoMatchDeclStr);
+ }
+
+ if ((prevOnMultipleMatchStr != null) && (onMultipleMatchStr != null)
+ && onMultipleMatchStr.equals(prevOnMultipleMatchStr)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration for an unnamed mode, that "
+ + "have conflicting values for \"xsl:mode\" "
+ + "attribute 'on-multiple-match'.");
+ }
+ else if ((prevOnMultipleMatchStr != null) && (onMultipleMatchStr == null)) {
+ elemMode.setOnMultipleMatch(prevOnMultipleMatchStr);
+ }
+
+ if (prevWarningOnNoMatchDeclared && warningOnNoMatchDeclared && (prevWarningOnNoMatch != warningOnNoMatch)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration for an unnamed mode, that "
+ + "have conflicting values for \"xsl:mode\" "
+ + "attribute 'warning-on-no-match'.");
+ }
+
+ if (prevWarningOnMultipleMatchDeclared && warningOnMultipleMatchDeclared && (prevWarningOnMultipleMatch != warningOnMultipleMatch)) {
+ throw new TransformerException("XTSE0545 : An XSL stylesheet has more than one xsl:mode declaration for an unnamed mode, that "
+ + "have conflicting values for \"xsl:mode\" "
+ + "attribute 'warning-on-multiple-match'.");
+ }
+
+ elemMode.setStylesheet(this);
+ m_defaultElemMode = elemMode;
}
- }
-
- elemMode.setStylesheet(this);
+ }
}
/**
@@ -1143,20 +1273,24 @@ public class Stylesheet extends ElemTemplateElement implements java.io.Serializa
*/
public ElemMode getElemMode(QName modeName) {
- ElemMode result = null;
+ ElemMode result = null;
- QName defaultMode = new QName("http://xml.apache.org/xalan", "default", true);
-
- if (modeName != null) {
- if (defaultMode.equals(modeName) && (m_defaultMode != null)) {
- result = m_defaultMode;
+ if (modeName != null) {
+ if ((m_xsl_default_mode != null) && (m_modeList != null)) {
+ result = m_modeList.getElemMode(m_xsl_default_mode);
+ }
+ else if (m_defaultElemMode != null) {
+ result = m_defaultElemMode;
}
else if (m_modeList != null) {
- result = m_modeList.getElemMode(modeName);
+ result = m_modeList.getElemMode(modeName);
}
}
- else if (m_defaultMode != null) {
- result = m_defaultMode;
+ else if ((m_xsl_default_mode != null) && (m_modeList != null)) {
+ result = m_modeList.getElemMode(m_xsl_default_mode);
+ }
+ else if (m_defaultElemMode != null) {
+ result = m_defaultElemMode;
}
return result;
diff --git a/src/main/java/org/apache/xalan/templates/StylesheetRoot.java b/src/main/java/org/apache/xalan/templates/StylesheetRoot.java
index d1cfc3ee6..a583eba78 100644
--- a/src/main/java/org/apache/xalan/templates/StylesheetRoot.java
+++ b/src/main/java/org/apache/xalan/templates/StylesheetRoot.java
@@ -1126,7 +1126,7 @@ public class StylesheetRoot extends StylesheetComposed
elemTemplate.appendChild(elemApplyTemplates);
}
else if (nodeType == DTM.ELEMENT_NODE) {
- XPath xpathMatch = new XPath("element()", this, this, XPath.MATCH, m_errorListener);
+ XPath xpathMatch = new XPath("*", this, this, XPath.MATCH, m_errorListener);
elemTemplate.setMatch(xpathMatch);
ElemApplyTemplates elemApplyTemplates = new ElemApplyTemplates();
@@ -1282,7 +1282,7 @@ public class StylesheetRoot extends StylesheetComposed
elemTemplate.appendChild(elemApplyTemplates2);
}
else if (nodeType == DTM.ELEMENT_NODE) {
- XPath xpathMatch = new XPath("element()", this, this, XPath.MATCH, m_errorListener);
+ XPath xpathMatch = new XPath("*", this, this, XPath.MATCH, m_errorListener);
elemTemplate.setMatch(xpathMatch);
ElemApplyTemplates elemApplyTemplates1 = new ElemApplyTemplates();
diff --git a/src/main/java/org/apache/xalan/templates/TemplateList.java b/src/main/java/org/apache/xalan/templates/TemplateList.java
index 5f6a860be..4754cacd6 100644
--- a/src/main/java/org/apache/xalan/templates/TemplateList.java
+++ b/src/main/java/org/apache/xalan/templates/TemplateList.java
@@ -26,12 +26,12 @@ import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
+import javax.xml.transform.ErrorListener;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xml.dtm.DTM;
-import org.apache.xml.utils.DefaultErrorHandler;
import org.apache.xml.utils.QName;
import org.apache.xpath.Expression;
import org.apache.xpath.XPath;
@@ -869,6 +869,12 @@ public class TemplateList implements java.io.Serializable
while ((next = next.getNext()) != null) {
if ((next.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE)
&& next.matchMode(mode)) {
+ /**
+ * Emitting an XSL stylesheet dynamic error, when xsl:mode
+ * instruction specifies an attribute "on-multiple-match" with
+ * value 'fail'.
+ */
+
String elemName = dtm.getNodeName(targetNode);
SourceLocator srcLocator1 = (SourceLocator)(head.getTemplate());
@@ -877,9 +883,9 @@ public class TemplateList implements java.io.Serializable
int lineNo2 = srcLocator2.getLineNumber();
throw new TransformerException("XTDE0540 : More than one xsl:template rule matched "
- + "an XML element node '" + elemName + "'. "
- + "Conflicting xsl:template rule locations are "
- + "line " + lineNo1 + " and line " + lineNo2 +".");
+ + "an XML element node '" + elemName + "'. "
+ + "Conflicting xsl:template rule locations are "
+ + "line " + lineNo1 + " and line " + lineNo2 +".", srcLocator1);
}
}
}
@@ -889,6 +895,12 @@ public class TemplateList implements java.io.Serializable
while ((next = next.getNext()) != null) {
if ((next.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE)
&& next.matchMode(mode)) {
+ /**
+ * Emitting an XSL stylesheet processing warning, when xsl:mode
+ * instruction specifies an attribute "warning-on-multiple-match" with
+ * value true.
+ */
+
String elemName = dtm.getNodeName(targetNode);
SourceLocator srcLocator1 = (SourceLocator)(head.getTemplate());
@@ -896,7 +908,8 @@ public class TemplateList implements java.io.Serializable
SourceLocator srcLocator2 = (SourceLocator)(next.getTemplate());
int lineNo2 = srcLocator2.getLineNumber();
- DefaultErrorHandler errorListener = new DefaultErrorHandler();
+ ErrorListener errorListener = xctxt.getErrorListener();
+
errorListener.warning(new TransformerException("Warning : More than one xsl:template rule matched "
+ "an XML element node '" + elemName + "'. "
+ "Conflicting xsl:template rule locations are "
diff --git a/src/main/java/org/apache/xalan/transformer/TransformerImpl.java b/src/main/java/org/apache/xalan/transformer/TransformerImpl.java
index dd37c3ac2..277f73052 100644
--- a/src/main/java/org/apache/xalan/transformer/TransformerImpl.java
+++ b/src/main/java/org/apache/xalan/transformer/TransformerImpl.java
@@ -3675,43 +3675,56 @@ public class TransformerImpl extends Transformer
throw new SAXNotRecognizedException(name);
}
-
- // %TODO% Doc
-
+
/**
- * NEEDSDOC Method getMode
- *
- *
- * NEEDSDOC (getMode) @return
+ * Get an XSL transformation's present mode value.
+ *
+ * @return QName object reference of the mode
*/
public QName getMode()
{
return m_modes.isEmpty() ? null : (QName) m_modes.peek();
}
-
- // %TODO% Doc
-
+
/**
- * NEEDSDOC Method pushMode
- *
- *
- * NEEDSDOC @param mode
+ * Push an XSL mode reference, to mode stack.
+ *
+ * @param mode QName object value of the mode
*/
public void pushMode(QName mode)
{
m_modes.push(mode);
}
- // %TODO% Doc
-
/**
- * NEEDSDOC Method popMode
- *
+ * Pop an XSL mode reference, from mode stack.
*/
public void popMode()
{
m_modes.pop();
}
+
+ /**
+ * Method definition, to get XSL transformation's current mode
+ * reference, for the given XSL evaluation context.
+ *
+ * @return QName object reference of the mode
+ */
+ public QName getCurrentMode() {
+
+ QName result = null;
+
+ if (!m_modes.isEmpty()) {
+ Object stackTop = m_modes.pop();
+ if ((stackTop != null) && !m_modes.isEmpty()) {
+ result = (QName)m_modes.peek();
+
+ m_modes.push(stackTop);
+ }
+ }
+
+ return null;
+ }
/**
* Called by SourceTreeHandler to start the transformation
diff --git a/src/test/java/org/apache/xalan/tests/w3c/xslt3/misc/XslBuiltInTemplateTests.java b/src/test/java/org/apache/xalan/tests/w3c/xslt3/misc/XslBuiltInTemplateTests.java
index ec43d500b..dac7fffc6 100644
--- a/src/test/java/org/apache/xalan/tests/w3c/xslt3/misc/XslBuiltInTemplateTests.java
+++ b/src/test/java/org/apache/xalan/tests/w3c/xslt3/misc/XslBuiltInTemplateTests.java
@@ -30,14 +30,6 @@ import org.junit.Test;
* @xsl.usage advanced
*/
public class XslBuiltInTemplateTests extends W3CXslTransformTestsUtil {
-
- /**
- * Xalan may probably have bugs for this W3C XSLT 3.0 test set.
- * Adding this XSLT 3.0 test set to Xalan's XSLT 3.0 test suite
- * driver, for tracking.
- *
- * REVISIT
- */
@BeforeClass
public static void setUpBeforeClass() throws Exception {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org