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/05/16 17:23:20 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xslt 3.0 instruction xsl:analyze-string. this is fairly complete, but is wip
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 3204b78e committing implementation of xslt 3.0 instruction xsl:analyze-string. this is fairly complete, but is wip
3204b78e is described below
commit 3204b78eda0a3e3e1158117615861dff46315185
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Tue May 16 22:52:29 2023 +0530
committing implementation of xslt 3.0 instruction xsl:analyze-string. this is fairly complete, but is wip
---
.../apache/xalan/processor/XSLTAttributeDef.java | 28 +-
src/org/apache/xalan/processor/XSLTSchema.java | 59 +++-
src/org/apache/xalan/templates/Constants.java | 13 +-
.../apache/xalan/templates/ElemAnalyzeString.java | 327 +++++++++++++++++++++
.../xalan/templates/ElemMatchingSubstring.java | 173 +++++++++++
.../xalan/templates/ElemNonMatchingSubstring.java | 194 ++++++++++++
src/org/apache/xml/dtm/DTMManager.java | 35 +++
.../xpath/functions/RegExFunctionSupport.java | 2 +-
8 files changed, 816 insertions(+), 15 deletions(-)
diff --git a/src/org/apache/xalan/processor/XSLTAttributeDef.java b/src/org/apache/xalan/processor/XSLTAttributeDef.java
index 07554134..cfb2c59c 100644
--- a/src/org/apache/xalan/processor/XSLTAttributeDef.java
+++ b/src/org/apache/xalan/processor/XSLTAttributeDef.java
@@ -41,8 +41,8 @@ import org.apache.xpath.XPath;
/**
* This class defines an attribute for an element in a XSLT stylesheet,
- * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
- * mapping between Xalan classes and the markup attributes in the element.
+ * and is meant to reflect the structure defined at https://www.w3.org/TR/xslt-30/#xsd11-schema-for-xslt,
+ * and the mapping between Xalan classes and the markup attributes in the element.
*/
public class XSLTAttributeDef
{
@@ -268,7 +268,10 @@ public class XSLTAttributeDef
// Used for a list of white-space delimited strings.
// strings are checked to make sure they are valid
// prefixes, and are not expanded when processed.
- T_PREFIXLIST = 20;
+ T_PREFIXLIST = 20,
+
+ // Used for a string value.
+ T_STRING = 21;
/** Representation for an attribute in a foreign namespace. */
static final XSLTAttributeDef m_foreignAttr = new XSLTAttributeDef("*", "*",
@@ -1210,6 +1213,22 @@ public class XSLTAttributeDef
return strings;
}
+
+ /**
+ * Process an attribute string of type T_STRING.
+ *
+ * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
+ * @param uri The Namespace URI, or an empty string.
+ * @param name The local name (without prefix), or empty string if not namespace processing.
+ * @param rawName The qualified name (with prefix).
+ * @param value String value.
+ *
+ * @return String value itself.
+ */
+ String processSTRING(StylesheetHandler handler, String uri, String name,
+ String rawName, String value) {
+ return value;
+ }
/**
* Process an attribute string of type T_URLLIST into
@@ -1435,6 +1454,9 @@ public class XSLTAttributeDef
case T_STRINGLIST :
processedValue = processSTRINGLIST(handler, uri, name, rawName, value);
break;
+ case T_STRING :
+ processedValue = processSTRING(handler, uri, name, rawName, value);
+ break;
case T_PREFIX_URLLIST :
processedValue = processPREFIX_URLLIST(handler, uri, name, rawName,
value);
diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index 7040cbd7..3faa0c65 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -23,6 +23,7 @@ package org.apache.xalan.processor;
import java.util.HashMap;
import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemAnalyzeString;
import org.apache.xalan.templates.ElemApplyImport;
import org.apache.xalan.templates.ElemApplyTemplates;
import org.apache.xalan.templates.ElemAttribute;
@@ -41,7 +42,9 @@ import org.apache.xalan.templates.ElemForEach;
import org.apache.xalan.templates.ElemForEachGroup;
import org.apache.xalan.templates.ElemIf;
import org.apache.xalan.templates.ElemLiteralResult;
+import org.apache.xalan.templates.ElemMatchingSubstring;
import org.apache.xalan.templates.ElemMessage;
+import org.apache.xalan.templates.ElemNonMatchingSubstring;
import org.apache.xalan.templates.ElemNumber;
import org.apache.xalan.templates.ElemOtherwise;
import org.apache.xalan.templates.ElemPI;
@@ -58,9 +61,10 @@ import org.apache.xalan.templates.ElemWithParam;
import org.apache.xml.utils.QName;
/**
- * This class defines the allowed structure for a stylesheet, and the
+ * This class defines the allowed structure for an XSLT stylesheet, and the
* mapping between Xalan classes and the markup elements in the stylesheet.
- * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ *
+ * @see <a href="https://www.w3.org/TR/xslt-30/#xsd11-schema-for-xslt">XSD 1.1 Schema for XSLT Stylesheets</a>
*/
public class XSLTSchema extends XSLTElementDef
{
@@ -74,8 +78,8 @@ public class XSLTSchema extends XSLTElementDef
}
/**
- * This method builds an XSLT "schema" according to http://www.w3.org/TR/xslt#dtd. This
- * schema provides instructions for building the Xalan Stylesheet (Templates) structure.
+ * This method builds an XSLT "schema" according to https://www.w3.org/TR/xslt-30/#xsd11-schema-for-xslt.
+ * This schema provides instructions for building the Xalan Stylesheet (Templates) structure.
*/
void build()
{
@@ -193,11 +197,23 @@ public class XSLTSchema extends XSLTElementDef
// Required.
- // xsl:value-of, xsl:for-each, xsl:copy-of, xsl:for-each-group
+ // xsl:value-of, xsl:for-each, xsl:copy-of, xsl:for-each-group, xsl:analyze-string
XSLTAttributeDef selectAttrRequired = new XSLTAttributeDef(null,
"select",
XSLTAttributeDef.T_EXPR, true, false, XSLTAttributeDef.ERROR);
+ // Required.
+ // xsl:analyze-string
+ XSLTAttributeDef regexAttrRequired = new XSLTAttributeDef(null,
+ "regex",
+ XSLTAttributeDef.T_STRING, true, false, XSLTAttributeDef.ERROR);
+
+ // Optional.
+ // xsl:analyze-string
+ XSLTAttributeDef flagsAttrOpt = new XSLTAttributeDef(null,
+ "flags",
+ XSLTAttributeDef.T_STRING, false, false, XSLTAttributeDef.ERROR);
+
// Optional.
// xsl:for-each-group
XSLTAttributeDef groupByAttrOpt = new XSLTAttributeDef(null,
@@ -368,11 +384,11 @@ public class XSLTSchema extends XSLTElementDef
new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "*",
XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.WARNING);
- XSLTElementDef[] templateElements = new XSLTElementDef[24];
- XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[25];
- XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[25];
+ XSLTElementDef[] templateElements = new XSLTElementDef[27];
+ XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[28];
+ XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[28];
//exslt
- XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[25];
+ XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[28];
XSLTElementDef[] charTemplateElements = new XSLTElementDef[16];
XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
@@ -479,6 +495,28 @@ public class XSLTSchema extends XSLTElementDef
new ProcessorTemplateElem(),
ElemForEachGroup.class /* class object */, true, false, true, 20, true);
+ XSLTElementDef xslAnalyzeString = new XSLTElementDef(this,
+ Constants.S_XSLNAMESPACEURL, "analyze-string",
+ null /*alias */, templateElements,
+ new XSLTAttributeDef[]{ selectAttrRequired,
+ regexAttrRequired, flagsAttrOpt, spaceAttr },
+ new ProcessorTemplateElem(),
+ ElemAnalyzeString.class /* class object */, true, false, true, 20, true);
+
+ XSLTElementDef xslMatchingSubstring = new XSLTElementDef(this,
+ Constants.S_XSLNAMESPACEURL, "matching-substring",
+ null /*alias */, templateElements,
+ new XSLTAttributeDef[] { },
+ new ProcessorTemplateElem(),
+ ElemMatchingSubstring.class /* class object */, true, false, true, 20, true);
+
+ XSLTElementDef xslNonMatchingSubstring = new XSLTElementDef(this,
+ Constants.S_XSLNAMESPACEURL, "non-matching-substring",
+ null /*alias */, templateElements,
+ new XSLTAttributeDef[] { },
+ new ProcessorTemplateElem(),
+ ElemNonMatchingSubstring.class /* class object */, true, false, true, 20, true);
+
XSLTElementDef xslIf = new XSLTElementDef(this,
Constants.S_XSLNAMESPACEURL,
"if", null /*alias */,
@@ -629,6 +667,9 @@ public class XSLTSchema extends XSLTElementDef
templateElements[i++] = xslApplyImports;
templateElements[i++] = xslForEach;
templateElements[i++] = xslForEachGroup;
+ templateElements[i++] = xslAnalyzeString;
+ templateElements[i++] = xslMatchingSubstring;
+ templateElements[i++] = xslNonMatchingSubstring;
templateElements[i++] = xslValueOf;
templateElements[i++] = xslCopyOf;
templateElements[i++] = xslNumber;
diff --git a/src/org/apache/xalan/templates/Constants.java b/src/org/apache/xalan/templates/Constants.java
index 8545fe85..83692489 100644
--- a/src/org/apache/xalan/templates/Constants.java
+++ b/src/org/apache/xalan/templates/Constants.java
@@ -88,9 +88,15 @@ public class Constants extends org.apache.xml.utils.Constants
ELEMNAME_EXTENSIONSCRIPT = 86, ELEMNAME_OUTPUT = 80,
ELEMNAME_COMPONENT = 81, ELEMNAME_SCRIPT = 82,
- ELEMNAME_FOREACHGROUP = 90;
+ ELEMNAME_FOREACHGROUP = 90,
- // Next free number: 91
+ ELEMNAME_ANALYZESTRING = 91,
+
+ ELEMNAME_MATCHING_SUBSTRING = 92,
+
+ ELEMNAME_NON_MATCHING_SUBSTRING = 93;
+
+ // next available number : 94
/**
* Literals for XSL element names. Note that there are more
@@ -132,6 +138,9 @@ public class Constants extends org.apache.xml.utils.Constants
ELEMNAME_FALLBACK_STRING = "fallback",
ELEMNAME_FOREACH_STRING = "for-each",
ELEMNAME_FOREACHGROUP_STRING = "for-each-group",
+ ELEMNAME_ANALYZESTRING_STRING = "analyze-string",
+ ELEMNAME_MATCHINGSUBSTRING_STRING = "matching-substring",
+ ELEMNAME_NONMATCHINGSUBSTRING_STRING = "non-matching-substring",
ELEMNAME_IF_STRING = "if",
ELEMNAME_IMPORT_STRING = "import",
ELEMNAME_INCLUDE_STRING = "include",
diff --git a/src/org/apache/xalan/templates/ElemAnalyzeString.java b/src/org/apache/xalan/templates/ElemAnalyzeString.java
new file mode 100644
index 00000000..668e75c2
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemAnalyzeString.java
@@ -0,0 +1,327 @@
+/*
+ * 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.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.RegExFunctionSupport;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.regex.Matcher;
+
+/**
+ * XSLT 3.0 analyze-string element.
+ *
+ * <xsl:analyze-string
+ select = expression
+ regex = { string }
+ flags? = { string } >
+ <!-- Content: (xsl:matching-substring?, xsl:non-matching-substring?, xsl:fallback*) -->
+ </xsl:analyze-string>
+
+ <xsl:matching-substring>
+ <!-- Content: sequence-constructor -->
+ </xsl:matching-substring>
+
+ <xsl:non-matching-substring>
+ <!-- Content: sequence-constructor -->
+ </xsl:non-matching-substring>
+
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+
+/*
+ * Implementation of the XSLT 3.0 xsl:analyze-string instruction.
+ *
+ * This XSLT instruction is intended to process, all the 'non overlapping' substrings
+ * of the input string that match the provided regular expression.
+ *
+ * The XSLT function fn:regex-group may be used optionally along with XSLT instruction
+ * xsl:analyze-string. // revisit
+ *
+ * With xsl:analyze-string element, we're presently not implementing xsl:fallback
+ * elements. xsl:fallback elements don't have much useful use cases, within
+ * xsl:analyze-string element. // revisit
+ *
+ */
+public class ElemAnalyzeString extends ElemTemplateElement implements ExpressionOwner {
+
+ private static final long serialVersionUID = 5892915527446791252L;
+
+ /**
+ * Constructor of this class.
+ */
+ public ElemAnalyzeString() {}
+
+ /**
+ * The "select" expression.
+ */
+ protected Expression m_selectExpression = null;
+
+ /**
+ * The "regex" expression.
+ */
+ protected String m_regex = null;
+
+ /**
+ * The regex "flags" expression.
+ */
+ protected String m_flags = null;
+
+ /**
+ * Set the "select" attribute.
+ *
+ * @param xpath The XPath expression for the "select" attribute.
+ */
+ public void setSelect(XPath xpath) {
+ m_selectExpression = xpath.getExpression();
+ }
+
+ /**
+ * Get the "select" attribute.
+ *
+ * @return The XPath expression for the "select" attribute.
+ */
+ public Expression getSelect() {
+ return m_selectExpression;
+ }
+
+ /**
+ * Set the "regex" attribute.
+ *
+ * @param regex The string value for the "regex" attribute.
+ */
+ public void setRegex(String regex) {
+ m_regex = regex;
+ }
+
+ /**
+ * Get the "regex" attribute.
+ *
+ * @return The string value for the "regex" attribute.
+ */
+ public String getRegex() {
+ return m_regex;
+ }
+
+ /**
+ * Set the "flags" attribute.
+ *
+ * @param regex The string value for the "flags" attribute.
+ */
+ public void setFlags(String flags) {
+ m_flags = flags;
+ }
+
+ /**
+ * Get the "flags" attribute.
+ *
+ * @return The string value for the "flags" attribute.
+ */
+ public String getFlags() {
+ return m_flags;
+ }
+
+ /**
+ * This function is called after everything else has been
+ * recomposed, and allows the template to set remaining
+ * values that may be based on some other property that
+ * depends on recomposition.
+ *
+ * @throws TransformerException
+ */
+ public void compose(StylesheetRoot sroot) throws TransformerException {
+
+ super.compose(sroot);
+
+ java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+ if (null != m_selectExpression) {
+ m_selectExpression.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
+ }
+ else {
+ m_selectExpression = getStylesheetRoot().m_selectDefault.getExpression();
+ }
+ }
+
+ /**
+ * This after the template's children have been composed.
+ */
+ public void endCompose(StylesheetRoot sroot) throws TransformerException {
+ super.endCompose(sroot);
+ }
+
+ /**
+ * Get an int constant identifying the type of element.
+ *
+ * @return The token ID for this element
+ */
+ public int getXSLToken() {
+ return Constants.ELEMNAME_ANALYZESTRING;
+ }
+
+ /**
+ * Return the node name.
+ *
+ * @return The element's name
+ */
+ public String getNodeName() {
+ return Constants.ELEMNAME_ANALYZESTRING_STRING;
+ }
+
+ /**
+ * Execute the XSLT element xsl:analyze-string's transformation.
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException
+ */
+ public void execute(TransformerImpl transformer) throws TransformerException {
+ transformSelectedNodes(transformer);
+ }
+
+ /**
+ * Get template element associated with this.
+ *
+ * @return template element associated with this (itself)
+ */
+ protected ElemTemplateElement getTemplateMatch() {
+ return this;
+ }
+
+ /**
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException Thrown in a variety of circumstances.
+ *
+ * @xsl.usage advanced
+ */
+ public void transformSelectedNodes(TransformerImpl transformer) throws TransformerException {
+
+ final XPathContext xctxt = transformer.getXPathContext();
+
+ XObject xpathEvalResult = m_selectExpression.execute(xctxt);
+
+ String strToBeAnalyzed = xpathEvalResult.str();
+
+ long currentTimeMills = System.currentTimeMillis();
+ String tempReplStr = (Long.valueOf(currentTimeMills)).toString();
+
+ if (m_flags != null && !RegExFunctionSupport.isFlagStrValid(m_flags)) {
+ throw new javax.xml.transform.TransformerException("XTDE1145 : Invalid regular expression flags are present, with "
+ + "xsl:analyze-string element.", xctxt.getSAXLocator());
+ }
+
+ Matcher regexMatcher = RegExFunctionSupport.compileAndExecute(RegExFunctionSupport.trfPatternStrForSubtraction(
+ m_regex), m_flags, strToBeAnalyzed);
+ String tempReplacedStr = regexMatcher.replaceAll(tempReplStr);
+
+ ElemTemplateElement templateElem1 = this.m_firstChild;
+ ElemTemplateElement templateElem2 = null;
+ ElemTemplateElement templateElem3 = null;
+
+ if (templateElem1 == null) {
+ throw new javax.xml.transform.TransformerException("XTSE1130 : At least one of the elements xsl:matching-substring or "
+ + "xsl:non-matching-substring must be present within xsl:analyze-string "
+ + "element.", xctxt.getSAXLocator());
+ }
+ else {
+ templateElem2 = templateElem1.m_nextSibling;
+ if (templateElem2 != null) {
+ if (!((templateElem1 instanceof ElemMatchingSubstring) && (templateElem2 instanceof ElemNonMatchingSubstring))) {
+ throw new javax.xml.transform.TransformerException("XTSE0010 : xsl:matching-substring element must come first within "
+ + "xsl:analyze-string element.", xctxt.getSAXLocator());
+ }
+ templateElem3 = templateElem2.m_nextSibling;
+ if (templateElem3 != null) {
+ throw new javax.xml.transform.TransformerException("XTSE0010 : Only xsl:matching-substring and xsl:non-matching-substring "
+ + "elements are allowed within xsl:analyze-string "
+ + "element.", xctxt.getSAXLocator());
+ }
+ }
+ }
+
+ String[] strParts = tempReplacedStr.split(tempReplStr);
+ for (int idx = 0; idx < strParts.length; idx++) {
+ if (templateElem2 != null) {
+ ((ElemNonMatchingSubstring)templateElem2).setStrValue(strParts[idx]);
+ xctxt.setSAXLocator(templateElem2);
+ transformer.setCurrentElement(templateElem2);
+ templateElem2.execute(transformer);
+ }
+
+ // ((ElemMatchingSubstring)templateElem1).setStrValue("???"); // revisit
+ xctxt.setSAXLocator(templateElem1);
+ transformer.setCurrentElement(templateElem1);
+ templateElem1.execute(transformer);
+ }
+
+ }
+
+ /**
+ *
+ * @param newChild Child to add to child list
+ *
+ * @return Child just added to child list
+ */
+ public ElemTemplateElement appendChild(ElemTemplateElement newChild)
+ {
+ return super.appendChild(newChild);
+ }
+
+ /**
+ * Call the children visitors.
+ *
+ * @param visitor The visitor whose appropriate method will be called.
+ */
+ public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes)
+ {
+ if (callAttributes && (null != m_selectExpression)) {
+ m_selectExpression.callVisitors(this, visitor);
+ }
+
+ super.callChildVisitors(visitor, callAttributes);
+ }
+
+ /**
+ * @see ExpressionOwner#getExpression()
+ */
+ public Expression getExpression() {
+ return m_selectExpression;
+ }
+
+ /**
+ * @see ExpressionOwner#setExpression(Expression)
+ */
+ public void setExpression(Expression exp) {
+ exp.exprSetParent(this);
+ m_selectExpression = exp;
+ }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemMatchingSubstring.java b/src/org/apache/xalan/templates/ElemMatchingSubstring.java
new file mode 100644
index 00000000..774ea943
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemMatchingSubstring.java
@@ -0,0 +1,173 @@
+/*
+ * 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.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+
+/**
+ XSLT 3.0 matching-substring element.
+
+ <xsl:matching-substring>
+ <!-- Content: sequence-constructor -->
+ </xsl:matching-substring>
+
+ @author Mukul Gandhi <mu...@apache.org>
+
+ * @xsl.usage advanced
+ */
+
+/*
+ * Implementation of the XSLT 3.0 xsl:matching-substring instruction.
+ *
+ * This XSLT element can only be used within the element xsl:analyze-string.
+ *
+ */
+public class ElemMatchingSubstring extends ElemTemplateElement implements ExpressionOwner {
+
+ private static final long serialVersionUID = -5675647188821169056L;
+
+ private String m_strValue = null;
+
+ /**
+ * Constructor of this class.
+ */
+ public ElemMatchingSubstring(){}
+
+ /**
+ * This function is called after everything else has been
+ * recomposed, and allows the template to set remaining
+ * values that may be based on some other property that
+ * depends on recomposition.
+ *
+ * @throws TransformerException
+ */
+ public void compose(StylesheetRoot sroot) throws TransformerException {
+ super.compose(sroot);
+ }
+
+ /**
+ * This after the template's children have been composed.
+ */
+ public void endCompose(StylesheetRoot sroot) throws TransformerException {
+ super.endCompose(sroot);
+ }
+
+ /**
+ * Get an int constant identifying the type of element.
+ * @see org.apache.xalan.templates.Constants
+ *
+ * @return The token ID for this element
+ */
+ public int getXSLToken() {
+ return Constants.ELEMNAME_MATCHING_SUBSTRING;
+ }
+
+ /**
+ * Return the node name.
+ *
+ * @return The element's name
+ */
+ public String getNodeName() {
+ return Constants.ELEMNAME_MATCHINGSUBSTRING_STRING;
+ }
+
+ /**
+ * Execute the xsl:matching-substring transformation
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException
+ */
+ public void execute(TransformerImpl transformer) throws TransformerException {
+ transformSelectedNodes(transformer);
+ }
+
+ /**
+ * Get template element associated with this
+ *
+ * @return template element associated with this (itself)
+ */
+ protected ElemTemplateElement getTemplateMatch() {
+ return this;
+ }
+
+ /**
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException Thrown in a variety of circumstances.
+ *
+ * @xsl.usage advanced
+ */
+ public void transformSelectedNodes(TransformerImpl transformer) throws TransformerException {
+
+ final XPathContext xctxt = transformer.getXPathContext();
+
+ for (ElemTemplateElement elem = this.m_firstChild; elem != null;
+ elem = elem.m_nextSibling) {
+ xctxt.setSAXLocator(elem);
+ transformer.setCurrentElement(elem);
+ elem.execute(transformer);
+ }
+ }
+
+ /**
+
+ * @param newChild Child to add to child list
+ *
+ * @return Child just added to child list
+ */
+ public ElemTemplateElement appendChild(ElemTemplateElement newChild) {
+ return super.appendChild(newChild);
+ }
+
+ /**
+ * Call the children visitors.
+ *
+ * @param visitor The visitor whose appropriate method will be called.
+ */
+ public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes) {
+ super.callChildVisitors(visitor, callAttributes);
+ }
+
+ @Override
+ public Expression getExpression() {
+ return null;
+ }
+
+ @Override
+ public void setExpression(Expression exp) {
+ // NO OP
+ }
+
+ public String getStrValue() {
+ return m_strValue;
+ }
+
+ public void setStrValue(String m_strValue) {
+ this.m_strValue = m_strValue;
+ }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java b/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java
new file mode 100644
index 00000000..7a810e31
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java
@@ -0,0 +1,194 @@
+/*
+ * 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.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPathContext;
+
+/**
+ XSLT 3.0 non-matching-substring element.
+
+ <xsl:non-matching-substring>
+ <!-- Content: sequence-constructor -->
+ </xsl:non-matching-substring>
+
+ @author Mukul Gandhi <mu...@apache.org>
+
+ * @xsl.usage advanced
+ */
+
+/*
+ * Implementation of the XSLT 3.0 xsl:non-matching-substring instruction.
+ *
+ * This XSLT element can only be used within the element xsl:analyze-string.
+ *
+ */
+public class ElemNonMatchingSubstring extends ElemTemplateElement implements ExpressionOwner {
+
+ private static final long serialVersionUID = -3993288598365914097L;
+
+ private String m_strValue = null;
+
+ /**
+ * Constructor of this class.
+ */
+ public ElemNonMatchingSubstring(){}
+
+ /**
+ * This function is called after everything else has been
+ * recomposed, and allows the template to set remaining
+ * values that may be based on some other property that
+ * depends on recomposition.
+ *
+ * @throws TransformerException
+ */
+ public void compose(StylesheetRoot sroot) throws TransformerException {
+ super.compose(sroot);
+ }
+
+ /**
+ * This after the template's children have been composed.
+ */
+ public void endCompose(StylesheetRoot sroot) throws TransformerException {
+ super.endCompose(sroot);
+ }
+
+ /**
+ * Get an int constant identifying the type of element.
+ * @see org.apache.xalan.templates.Constants
+ *
+ * @return The token ID for this element
+ */
+ public int getXSLToken() {
+ return Constants.ELEMNAME_NON_MATCHING_SUBSTRING;
+ }
+
+ /**
+ * Return the node name.
+ *
+ * @return The element's name
+ */
+ public String getNodeName() {
+ return Constants.ELEMNAME_NONMATCHINGSUBSTRING_STRING;
+ }
+
+ /**
+ * Execute the non-matching-substring transformation.
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException
+ */
+ public void execute(TransformerImpl transformer) throws TransformerException {
+ transformSelectedNodes(transformer);
+ }
+
+ /**
+ * Get template element associated with this.
+ *
+ * @return template element associated with this (itself)
+ */
+ protected ElemTemplateElement getTemplateMatch() {
+ return this;
+ }
+
+ /**
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException Thrown in a variety of circumstances.
+ *
+ * @xsl.usage advanced
+ */
+ public void transformSelectedNodes(TransformerImpl transformer) throws TransformerException {
+
+ final XPathContext xctxt = transformer.getXPathContext();
+
+ String strValueTobeEvaluated = getStrValue();
+
+ XPathContext xctxtNew = new XPathContext(false);
+
+ DTMManager dtmMgr = xctxtNew.getDTMManager();
+ DTM docFragDtm = dtmMgr.createDTMForSimpleXMLDocument(strValueTobeEvaluated);
+
+ int contextNode = docFragDtm.getFirstChild(docFragDtm.getDocument());
+
+ for (ElemTemplateElement elem = this.m_firstChild; elem != null;
+ elem = elem.m_nextSibling) {
+ xctxtNew.pushCurrentNode(contextNode);
+ xctxtNew.setSAXLocator(elem);
+ transformer.setXPathContext(xctxtNew);
+ transformer.setCurrentElement(elem);
+ elem.execute(transformer);
+ }
+
+ // restore the XPath context to where that was, before this method was called
+ transformer.setXPathContext(xctxt);
+ }
+
+ /**
+ *
+ * @param newChild Child to add to child list
+ *
+ * @return Child just added to child list
+ */
+ public ElemTemplateElement appendChild(ElemTemplateElement newChild) {
+ return super.appendChild(newChild);
+ }
+
+ /**
+ * Call the children visitors.
+ *
+ * @param visitor The visitor whose appropriate method will be called.
+ */
+ public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes) {
+ super.callChildVisitors(visitor, callAttributes);
+ }
+
+ /**
+ * @see ExpressionOwner#getExpression()
+ */
+ public Expression getExpression() {
+ return null;
+ }
+
+ /**
+ * @see ExpressionOwner#setExpression(Expression)
+ */
+ public void setExpression(Expression exp) {
+ // NO OP
+ }
+
+ public String getStrValue() {
+ return m_strValue;
+ }
+
+ public void setStrValue(String m_strValue) {
+ this.m_strValue = m_strValue;
+ }
+
+}
diff --git a/src/org/apache/xml/dtm/DTMManager.java b/src/org/apache/xml/dtm/DTMManager.java
index ac468fd3..771cf387 100644
--- a/src/org/apache/xml/dtm/DTMManager.java
+++ b/src/org/apache/xml/dtm/DTMManager.java
@@ -20,10 +20,17 @@
*/
package org.apache.xml.dtm;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.dom.DOMSource;
+
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.XMLStringFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
/**
* A DTMManager instance can be used to create DTM and
@@ -208,6 +215,34 @@ public abstract class DTMManager
* @return a non-null DTM reference.
*/
public abstract DTM createDocumentFragment();
+
+ /*
+ * This method has been defined, to construct a DTM object, representing an
+ * XML document that contains only 'one xml element with a text node child'.
+ * This method currently supports, evaluation of XSLT xsl:analyze-string
+ * instruction.
+ */
+ public DTM createDTMForSimpleXMLDocument(String strVal) {
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+ dbf.setNamespaceAware(true);
+
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document doc = db.newDocument();
+ // "temp" is an arbitrary name selected for an XML element,
+ // for this purpose.
+ Element elem = doc.createElement("temp");
+ Text textNode = doc.createTextNode(strVal);
+ elem.appendChild(textNode);
+ doc.appendChild(elem);
+
+ return getDTM(new DOMSource(doc), true, null, false, false);
+ }
+ catch (Exception e) {
+ throw new DTMException(e);
+ }
+ }
/**
* Release a DTM either to a lru pool, or completely remove reference.
diff --git a/src/org/apache/xpath/functions/RegExFunctionSupport.java b/src/org/apache/xpath/functions/RegExFunctionSupport.java
index 0f0f25c3..0783424a 100644
--- a/src/org/apache/xpath/functions/RegExFunctionSupport.java
+++ b/src/org/apache/xpath/functions/RegExFunctionSupport.java
@@ -75,7 +75,7 @@ public class RegExFunctionSupport {
return flagStrValid;
}
- private static Matcher compileAndExecute(String pattern, String flags, String src) {
+ public static Matcher compileAndExecute(String pattern, String flags, String src) {
int flag = Pattern.UNIX_LINES;
if (flags != null) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org