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/31 09:20:06 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 function fn:contains-token, along with few new related test cases as well. also committing implementation of 'html ascii case-insensitive collation', as described by xpath 3.1 f&o spec.
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 745bda3c committing implementation of xpath 3.1 function fn:contains-token, along with few new related test cases as well. also committing implementation of 'html ascii case-insensitive collation', as described by xpath 3.1 f&o spec.
new 865966b0 Merge pull request #71 from mukulga/xalan-j_xslt3.0_mukul
745bda3c is described below
commit 745bda3cc9167c778290007beccb6702f7a6f022
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Thu Aug 31 14:44:51 2023 +0530
committing implementation of xpath 3.1 function fn:contains-token, along with few new related test cases as well. also committing implementation of 'html ascii case-insensitive collation', as described by xpath 3.1 f&o spec.
---
src/org/apache/xpath/XPathCollationSupport.java | 50 +++++-
src/org/apache/xpath/compiler/FunctionTable.java | 9 +-
src/org/apache/xpath/compiler/Keywords.java | 3 +
.../apache/xpath/functions/FuncContainsToken.java | 190 +++++++++++++++++++++
tests/fn_containstoken/gold/test1.out | 6 +
tests/fn_containstoken/gold/test2.out | 7 +
tests/fn_containstoken/test1.xsl | 55 ++++++
tests/fn_containstoken/test1_a.xml | 7 +
tests/fn_containstoken/test2.xsl | 58 +++++++
.../apache/xalan/xpath3/FnContainsTokenTests.java | 72 ++++++++
tests/org/apache/xalan/xslt3/AllXsl3Tests.java | 3 +-
11 files changed, 455 insertions(+), 5 deletions(-)
diff --git a/src/org/apache/xpath/XPathCollationSupport.java b/src/org/apache/xpath/XPathCollationSupport.java
index 64569389..972382cc 100644
--- a/src/org/apache/xpath/XPathCollationSupport.java
+++ b/src/org/apache/xpath/XPathCollationSupport.java
@@ -132,9 +132,53 @@ public class XPathCollationSupport {
}
}
else if (HTML_ASCII_CASE_INSENSITIVE_COLLATION_URI.equals(collationUri)) {
- // REVISIT
- throw new javax.xml.transform.TransformerException("FOCH0002 : The requested collation '" + collationUri + "' "
- + "is not supported.");
+ int str1Len = str1.length();
+ int str2Len = str2.length();
+
+ int idx1 = 0;
+ int idx2 = 0;
+
+ while (true) {
+ if (idx1 == str1Len) {
+ if (idx2 == str2Len) {
+ comparisonResult = 0;
+ break;
+ } else {
+ comparisonResult = -1;
+ break;
+ }
+ }
+
+ if (idx2 == str2Len) {
+ comparisonResult = 1;
+ break;
+ }
+
+ int codepoint1 = str1.codePointAt(idx1);
+ idx1 += 1;
+
+ int codepoint2 = str2.codePointAt(idx2);
+ idx2 += 1;
+
+ if ((codepoint1 >= 'a') && (codepoint1 <= 'z')) {
+ codepoint1 += 'A' - 'a';
+ }
+
+ if ((codepoint2 >= 'a') && (codepoint2 <= 'z')) {
+ codepoint2 += 'A' - 'a';
+ }
+
+ int codepointDiff = codepoint1 - codepoint2;
+ if (codepointDiff != 0) {
+ if (codepointDiff < 0) {
+ comparisonResult = -1;
+ }
+ else {
+ comparisonResult = 1;
+ }
+ break;
+ }
+ }
}
else {
throw new javax.xml.transform.TransformerException("FOCH0002 : The requested collation '" + collationUri + "' "
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 7b62e43f..0b72faac 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -317,6 +317,9 @@ public class FunctionTable
/** The 'min()' id. */
public static final int FUNC_MIN = 97;
+
+ /** The 'contains-token()' id. */
+ public static final int FUNC_CONTAINS_TOKEN = 98;
// Proprietary
@@ -374,7 +377,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 = 98;
+ private static final int NUM_BUILT_IN_FUNCS = 99;
/**
* Number of built-in functions that may be added.
@@ -541,6 +544,8 @@ public class FunctionTable
org.apache.xpath.functions.FuncCompare.class;
m_functions[FUNC_CODEPOINT_EQUAL] =
org.apache.xpath.functions.FuncCodepointEqual.class;
+ m_functions[FUNC_CONTAINS_TOKEN] =
+ org.apache.xpath.functions.FuncContainsToken.class;
m_functions[FUNC_EMPTY] =
org.apache.xpath.functions.FuncEmpty.class;
@@ -742,6 +747,8 @@ public class FunctionTable
new Integer(FunctionTable.FUNC_COMPARE));
m_functionID.put(Keywords.FUNC_CODEPOINT_EQUAL,
new Integer(FunctionTable.FUNC_CODEPOINT_EQUAL));
+ m_functionID.put(Keywords.FUNC_CONTAINS_TOKEN,
+ new Integer(FunctionTable.FUNC_CONTAINS_TOKEN));
m_functionID.put(Keywords.FUNC_EMPTY,
new Integer(FunctionTable.FUNC_EMPTY));
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index fa281598..cf7a46dc 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -353,6 +353,9 @@ public class Keywords
/** codepoint-equal function string. */
public static final String FUNC_CODEPOINT_EQUAL = "codepoint-equal";
+ /** contains-token function string. */
+ public static final String FUNC_CONTAINS_TOKEN = "contains-token";
+
// XML Schema built-in data type name keywords
/** xs:string data type string. */
diff --git a/src/org/apache/xpath/functions/FuncContainsToken.java b/src/org/apache/xpath/functions/FuncContainsToken.java
new file mode 100644
index 00000000..f0a47ffa
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncContainsToken.java
@@ -0,0 +1,190 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathCollationSupport;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.xs.types.XSBoolean;
+
+/**
+ * Implementation of an XPath 3.1 function contains-token().
+ *
+ * Ref : https://www.w3.org/TR/xpath-functions-31/#func-contains-token
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FuncContainsToken extends FunctionMultiArgs {
+
+ private static final long serialVersionUID = -7113398825278491809L;
+
+ /**
+ * 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
+ {
+ ResultSequence result = new ResultSequence();
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ Expression arg0 = getArg0();
+ Expression arg1 = getArg1();
+ Expression arg2 = getArg2();
+
+ if ((arg0 == null) || (arg1 == null)) {
+ // return an empty sequence, if first two mandatory arguments are not
+ // present within function call fn:contains-token.
+ return result;
+ }
+
+ XObject arg0EvalResult = arg0.execute(xctxt);
+
+ List<String> arg0StrList = new ArrayList<String>();
+
+ if (arg0EvalResult instanceof XNodeSet) {
+ XNodeSet nodeSet = (XNodeSet)arg0EvalResult;
+ if (nodeSet.getLength() > 0) {
+ DTMManager dtmMgr = (DTMManager)xctxt;
+ DTMIterator sourceNodes = nodeSet.iter();
+
+ int nextNodeDtmHandle;
+ while ((nextNodeDtmHandle = sourceNodes.nextNode()) != DTM.NULL) {
+ XNodeSet xNodeSetItem = new XNodeSet(nextNodeDtmHandle, dtmMgr);
+ String strVal = xNodeSetItem.str();
+ arg0StrList.add(strVal);
+ }
+ }
+ else {
+ result.add(new XSBoolean(false));
+ }
+ }
+ else if (arg0EvalResult instanceof ResultSequence) {
+ ResultSequence resultSeq = (ResultSequence)arg0EvalResult;
+ if (resultSeq.size() > 0) {
+ for (int idx = 0; idx < resultSeq.size(); idx++) {
+ XObject xObject = resultSeq.item(idx);
+ String strVal = XslTransformEvaluationHelper.getStrVal(xObject);
+ arg0StrList.add(strVal);
+ }
+ }
+ else {
+ result.add(new XSBoolean(false));
+ }
+ }
+ else {
+ arg0StrList.add(arg0EvalResult.str());
+ }
+
+ XObject arg1EvalResult = arg1.execute(xctxt);
+
+ String tokenStrVal = XslTransformEvaluationHelper.getStrVal(arg1EvalResult);
+ tokenStrVal = tokenStrVal.trim();
+
+ if (tokenStrVal.length() > 0) {
+ String collationUri = null;
+ if (arg2 == null) {
+ collationUri = xctxt.getDefaultCollation();
+ }
+ else {
+ XObject arg2EvalResult = arg2.execute(xctxt);
+ collationUri = XslTransformEvaluationHelper.getStrVal(arg2EvalResult);
+ }
+
+ XPathCollationSupport xpathCollationSupport = xctxt.getXPathCollationSupport();
+
+ boolean isTokenExists = false;
+
+ for (int idx1 = 0; idx1 < arg0StrList.size(); idx1++) {
+ String strVal = arg0StrList.get(idx1);
+ // split this string at whitespace boundaries
+ String[] strPartsArr = strVal.split("\s+");
+ for (int idx2 = 0; idx2 < strPartsArr.length; idx2++) {
+ String strPart = strPartsArr[idx2];
+ if (xpathCollationSupport.compareStringsUsingCollation(strPart, tokenStrVal,
+ collationUri) == 0) {
+ result.add(new XSBoolean(true));
+ isTokenExists = true;
+ break;
+ }
+ }
+
+ if (isTokenExists) {
+ break;
+ }
+ }
+
+ if (!isTokenExists) {
+ result.add(new XSBoolean(false));
+ }
+ }
+ else {
+ result.add(new XSBoolean(false));
+ }
+
+ return result;
+ }
+
+ /**
+ * Check that the number of arguments passed to this function is correct.
+ *
+ * @param argNum The number of arguments that is being passed to the function.
+ *
+ * @throws WrongNumberArgsException
+ */
+ public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+ {
+ if (!(argNum == 2 || argNum == 3)) {
+ reportWrongNumberArgs();
+ }
+ }
+
+ /**
+ * Constructs and throws a WrongNumberArgException with the appropriate
+ * message for this function object.
+ *
+ * @throws WrongNumberArgsException
+ */
+ protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+ throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(
+ XPATHErrorResources.ER_TWO_OR_THREE, null)); //"2 or 3"
+ }
+
+
+}
diff --git a/tests/fn_containstoken/gold/test1.out b/tests/fn_containstoken/gold/test1.out
new file mode 100644
index 00000000..304c06dc
--- /dev/null
+++ b/tests/fn_containstoken/gold/test1.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one>true</one>
+ <two>true</two>
+ <three>false</three>
+ <four>true</four>
+</result>
diff --git a/tests/fn_containstoken/gold/test2.out b/tests/fn_containstoken/gold/test2.out
new file mode 100644
index 00000000..fc9d73c6
--- /dev/null
+++ b/tests/fn_containstoken/gold/test2.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <one>true</one>
+ <two>false</two>
+ <three>true</three>
+ <four>true</four>
+ <five>false</five>
+</result>
diff --git a/tests/fn_containstoken/test1.xsl b/tests/fn_containstoken/test1.xsl
new file mode 100644
index 00000000..bf2f7dc5
--- /dev/null
+++ b/tests/fn_containstoken/test1.xsl
@@ -0,0 +1,55 @@
+<?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 -->
+
+ <!-- This XSLT stylesheet test case, tests the XPath 3.1 function
+ fn:contains-token.
+
+ Within this stylesheet, the XPath expression examples for the
+ function fn:contains-token are borrowed from XPath 3.1 F&O spec.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:variable name="seq1" select="('red', 'green', 'blue')"/>
+
+ <xsl:variable name="collationUri" select="'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive'"/>
+
+ <xsl:template match="/">
+ <result>
+ <one>
+ <xsl:value-of select="contains-token('red green blue ', 'red')"/>
+ </one>
+ <two>
+ <xsl:value-of select="contains-token($seq1, ' red ')"/>
+ </two>
+ <three>
+ <xsl:value-of select="contains-token('red, green, blue', 'red')"/>
+ </three>
+ <four>
+ <xsl:value-of select="contains-token('red green blue', 'RED', $collationUri)"/>
+ </four>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/fn_containstoken/test1_a.xml b/tests/fn_containstoken/test1_a.xml
new file mode 100644
index 00000000..0e40ab1e
--- /dev/null
+++ b/tests/fn_containstoken/test1_a.xml
@@ -0,0 +1,7 @@
+<info>
+ <val1>red green blue </val1>
+ <val2>red, green, blue</val2>
+ <val3>red green blue</val3>
+ <data1 val="red green blue "/>
+ <data2 val="red, green, blue"/>
+</info>
\ No newline at end of file
diff --git a/tests/fn_containstoken/test2.xsl b/tests/fn_containstoken/test2.xsl
new file mode 100644
index 00000000..b292699a
--- /dev/null
+++ b/tests/fn_containstoken/test2.xsl
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_a.xml -->
+
+ <!-- This XSLT stylesheet test case, tests the XPath 3.1 function
+ fn:contains-token.
+
+ This stylesheet example, reads input data to be transformed
+ from an XML external document.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:variable name="collationUri" select="'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive'"/>
+
+ <xsl:template match="/info">
+ <result>
+ <one>
+ <xsl:value-of select="contains-token(val1, 'red')"/>
+ </one>
+ <two>
+ <xsl:value-of select="contains-token(val2, 'red')"/>
+ </two>
+ <three>
+ <xsl:value-of select="contains-token(val3, 'RED', $collationUri)"/>
+ </three>
+ <four>
+ <xsl:value-of select="contains-token(data1/@val, 'red')"/>
+ </four>
+ <five>
+ <xsl:value-of select="contains-token(data2/@val, 'red')"/>
+ </five>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/org/apache/xalan/xpath3/FnContainsTokenTests.java b/tests/org/apache/xalan/xpath3/FnContainsTokenTests.java
new file mode 100644
index 00000000..a96ef428
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/FnContainsTokenTests.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:contains-token test cases.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class FnContainsTokenTests extends XslTransformTestsUtil {
+
+ private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX
+ + "fn_containstoken/";
+
+ private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX
+ + "fn_containstoken/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 xslFnContainsTokenTest1() {
+ 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 xslFnContainsTokenTest2() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+}
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index dcdc8216..9153e9b6 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -23,6 +23,7 @@ import org.apache.xalan.xpath3.FnAvgTests;
import org.apache.xalan.xpath3.FnCodepointEqualTests;
import org.apache.xalan.xpath3.FnCodepointsToStringTests;
import org.apache.xalan.xpath3.FnCompareTests;
+import org.apache.xalan.xpath3.FnContainsTokenTests;
import org.apache.xalan.xpath3.FnDistinctValuesTests;
import org.apache.xalan.xpath3.FnFilterTests;
import org.apache.xalan.xpath3.FnFoldLeftTests;
@@ -90,7 +91,7 @@ import org.junit.runners.Suite.SuiteClasses;
FnFoldRightTests.class, FnForEachPairTests.class, FnSortTests.class, FnCodepointsToStringTests.class,
FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
- TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class })
+ TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class })
public class AllXsl3Tests {
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org