mmidy 2002/06/27 08:01:19
Modified: java/src/org/apache/xpath/compiler XPathParser.java
java/src/org/apache/xpath/res XPATHErrorResources.java
XPATHErrorResources.properties
Log:
Bugzilla 5016: Patch from Henry Zongaro... Fix XPATHParser.java to prevent
matching empty RelativeLocationPath and Step expressions, prevent a
LocationPath from preceding a Predicate in a FilterExpr, check for valid
NameTest in NodeTest()
Revision Changes Path
1.21 +274 -96
xml-xalan/java/src/org/apache/xpath/compiler/XPathParser.java
Index: XPathParser.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/compiler/XPathParser.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- XPathParser.java 6 May 2002 18:45:28 -0000 1.20
+++ XPathParser.java 27 Jun 2002 15:01:19 -0000 1.21
@@ -110,6 +110,13 @@
int m_queueMark = 0;
/**
+ * Results from checking FilterExpr syntax
+ */
+ protected final static int FILTER_MATCH_FAILED = 0;
+ protected final static int FILTER_MATCH_PRIMARY = 1;
+ protected final static int FILTER_MATCH_PREDICATES = 2;
+
+ /**
* The parser constructor.
*/
public XPathParser(ErrorListener errorListener,
javax.xml.transform.SourceLocator sourceLocator)
@@ -1256,23 +1263,47 @@
{
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
- boolean foundLocationPath;
- FilterExpr();
+ int filterExprMatch = FilterExpr();
- if (tokenIs('/'))
+ if (filterExprMatch != FILTER_MATCH_FAILED)
{
- nextToken();
+ // If FilterExpr had Predicates, a OP_LOCATIONPATH opcode would already
+ // have been inserted.
+ boolean locationPathStarted =
(filterExprMatch==FILTER_MATCH_PREDICATES);
+
+ if (tokenIs('/'))
+ {
+ nextToken();
+
+ if (!locationPathStarted)
+ {
+ // int locationPathOpPos = opPos;
+ insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
+
+ locationPathStarted = true;
+ }
+
+ if (!RelativeLocationPath())
+ {
+ // "Relative location path expected following '/' or '//'"
+ error(XPATHErrorResources.ER_EXPECTED_REL_LOC_PATH, null);
+ }
- // int locationPathOpPos = opPos;
- insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
- RelativeLocationPath();
+ }
// Terminate for safety.
- m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
- m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+ if (locationPathStarted)
+ {
+ m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
+ m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
+ m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
+ m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+ }
+ }
+ else
+ {
+ LocationPath();
}
}
@@ -1285,40 +1316,48 @@
* @throws XSLProcessorException thrown if the active ProblemListener and
XPathContext decide
* the error condition is severe enough to halt processing.
*
+ * @return FILTER_MATCH_PREDICATES, if this method successfully matched a
+ * FilterExpr with one or more Predicates;
+ * FILTER_MATCH_PRIMARY, if this method successfully matched a
+ * FilterExpr that was just a PrimaryExpr; or
+ * FILTER_MATCH_FAILED, if this method did not match a FilterExpr
+ *
* @throws javax.xml.transform.TransformerException
*/
- protected void FilterExpr() throws javax.xml.transform.TransformerException
+ protected int FilterExpr() throws javax.xml.transform.TransformerException
{
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
- // boolean isFunc = lookahead('(', 1);
- PrimaryExpr();
+ int filterMatch;
- if (tokenIs('['))
+ if (PrimaryExpr())
{
+ if (tokenIs('['))
+ {
- // int locationPathOpPos = opPos;
- insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
+ // int locationPathOpPos = opPos;
+ insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
- while (tokenIs('['))
- {
- Predicate();
- }
+ while (tokenIs('['))
+ {
+ Predicate();
+ }
- if (tokenIs('/'))
+ filterMatch = FILTER_MATCH_PREDICATES;
+ }
+ else
{
- nextToken();
- RelativeLocationPath();
+ filterMatch = FILTER_MATCH_PRIMARY;
}
-
- // Terminate for safety.
- m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
- m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+ }
+ else
+ {
+ filterMatch = FILTER_MATCH_FAILED;
}
+ return filterMatch;
+
/*
* if(tokenIs('['))
* {
@@ -1336,12 +1375,15 @@
* | Number
* | FunctionCall
*
+ * @return true if this method successfully matched a PrimaryExpr
*
* @throws javax.xml.transform.TransformerException
+ *
*/
- protected void PrimaryExpr() throws
javax.xml.transform.TransformerException
+ protected boolean PrimaryExpr() throws
javax.xml.transform.TransformerException
{
+ boolean matchFound;
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
if ((m_tokenChar == '\'') || (m_tokenChar == '"'))
@@ -1351,6 +1393,8 @@
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ matchFound = true;
}
else if (m_tokenChar == '$')
{
@@ -1360,6 +1404,8 @@
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ matchFound = true;
}
else if (m_tokenChar == '(')
{
@@ -1370,6 +1416,8 @@
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ matchFound = true;
}
else if ((null != m_token) && ((('.' == m_tokenChar) &&
(m_token.length() > 1) && Character.isDigit(
m_token.charAt(1))) || Character.isDigit(m_tokenChar)))
@@ -1379,15 +1427,19 @@
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ matchFound = true;
}
else if (lookahead('(', 1) || (lookahead(':', 1) && lookahead('(', 3)))
{
- FunctionCall();
+ matchFound = FunctionCall();
}
else
{
- LocationPath();
+ matchFound = false;
}
+
+ return matchFound;
}
/**
@@ -1413,10 +1465,11 @@
*
* FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)?
')'
*
+ * @return true if, and only if, a FunctionCall was matched
*
* @throws javax.xml.transform.TransformerException
*/
- protected void FunctionCall() throws
javax.xml.transform.TransformerException
+ protected boolean FunctionCall() throws
javax.xml.transform.TransformerException
{
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
@@ -1450,9 +1503,8 @@
case OpCodes.NODETYPE_COMMENT :
case OpCodes.NODETYPE_TEXT :
case OpCodes.NODETYPE_NODE :
- LocationPath();
-
- return;
+ // Node type tests look like function calls, but they're not
+ return false;
default :
appendOp(3, OpCodes.OP_FUNCTION);
@@ -1492,6 +1544,8 @@
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ return true;
}
// ============= GRAMMAR FUNCTIONS =================
@@ -1512,7 +1566,9 @@
// int locationPathOpPos = opPos;
appendOp(2, OpCodes.OP_LOCATIONPATH);
- if (tokenIs('/'))
+ boolean seenSlash = tokenIs('/');
+
+ if (seenSlash)
{
appendOp(4, OpCodes.FROM_ROOT);
@@ -1526,7 +1582,13 @@
if (m_token != null)
{
- RelativeLocationPath();
+ if (!RelativeLocationPath() && !seenSlash)
+ {
+ // Neither a '/' nor a RelativeLocationPath - i.e., matched nothing
+ // "Location path expected, but found "+m_token+" was encountered."
+ error(XPATHErrorResources.ER_EXPECTED_LOC_PATH,
+ new Object [] {m_token});
+ }
}
// Terminate for safety.
@@ -1542,19 +1604,31 @@
* | RelativeLocationPath '/' Step
* | AbbreviatedRelativeLocationPath
*
+ * @returns true if, and only if, a RelativeLocationPath was matched
*
* @throws javax.xml.transform.TransformerException
*/
- protected void RelativeLocationPath() throws
javax.xml.transform.TransformerException
+ protected boolean RelativeLocationPath()
+ throws javax.xml.transform.TransformerException
{
-
- Step();
+ if (!Step())
+ {
+ return false;
+ }
while (tokenIs('/'))
{
nextToken();
- Step();
+
+ if (!Step())
+ {
+ // RelativeLocationPath can't end with a trailing '/'
+ // "Location step expected following '/' or '//'"
+ error(XPATHErrorResources.ER_EXPECTED_LOC_STEP, null);
+ }
}
+
+ return true;
}
/**
@@ -1562,13 +1636,47 @@
* Step ::= Basis Predicate
* | AbbreviatedStep
*
+ * @returns false if step was empty (or only a '/'); true, otherwise
+ *
* @throws javax.xml.transform.TransformerException
*/
- protected void Step() throws javax.xml.transform.TransformerException
+ protected boolean Step() throws javax.xml.transform.TransformerException
{
-
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
+ boolean doubleSlash = tokenIs('/');
+
+ // At most a single '/' before each Step is consumed by caller; if the
+ // first thing is a '/', that means we had '//' and the Step must not
+ // be empty.
+ if (doubleSlash)
+ {
+ nextToken();
+
+ appendOp(2, OpCodes.FROM_DESCENDANTS_OR_SELF);
+
+ // Have to fix up for patterns such as '//@foo' or '//attribute::foo',
+ // which translate to 'descendant-or-self::node()/attribute::foo'.
+ // notice I leave the '/' on the queue, so the next will be processed
+ // by a regular step pattern.
+
+ // Make room for telling how long the step is without the predicate
+ m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
+ m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] =
+ OpCodes.NODETYPE_NODE;
+ m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
+
+ // Tell how long the step is without the predicate
+ m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] =
+ m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ // Tell how long the step is with the predicate
+ m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
+ m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
+ }
+
if (tokenIs("."))
{
nextToken();
@@ -1599,8 +1707,8 @@
// There is probably a better way to test for this
// transition... but it gets real hairy if you try
// to do it in basis().
- else if (tokenIs('*') || tokenIs('@') || tokenIs('/')
- || tokenIs('_') || (m_token!= null &&
Character.isLetter(m_token.charAt(0))))
+ else if (tokenIs('*') || tokenIs('@') || tokenIs('_')
+ || (m_token!= null && Character.isLetter(m_token.charAt(0))))
{
Basis();
@@ -1613,6 +1721,19 @@
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
}
+ else
+ {
+ // No Step matched - that's an error if previous thing was a '//'
+ if (doubleSlash)
+ {
+ // "Location step expected following '/' or '//'"
+ error(XPATHErrorResources.ER_EXPECTED_LOC_STEP, null);
+ }
+
+ return false;
+ }
+
+ return true;
}
/**
@@ -1643,37 +1764,6 @@
appendOp(2, axesType);
nextToken();
}
- else if (tokenIs('/'))
- {
- axesType = OpCodes.FROM_DESCENDANTS_OR_SELF;
-
- appendOp(2, axesType);
-
- // Have to fix up for patterns such as '//@foo' or '//attribute::foo',
- // which translate to 'descendant-or-self::node()/attribute::foo'.
- // notice I leave the '/' on the queue, so the next will be processed
- // by a regular step pattern.
- // if(lookahead('@', 1) || lookahead("::", 2))
- {
-
- // Make room for telling how long the step is without the predicate
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
- m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] =
- OpCodes.NODETYPE_NODE;
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
- // Tell how long the step is without the predicate
- m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] =
- m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
- return; // make a quick exit...
- }
-
- // else
- // {
- // nextToken();
- // }
- }
else
{
axesType = OpCodes.FROM_CHILDREN;
@@ -1780,6 +1870,14 @@
{
m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark
- 1;
+
+ // Minimalist check for an NCName - just check first character
+ // to distinguish from other possible tokens
+ if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
+ {
+ // "Node test that matches either NCName:* or QName was
expected."
+ error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
+ }
}
nextToken();
@@ -1810,6 +1908,14 @@
}
m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark -
1;
+
+ // Minimalist check for an NCName - just check first character
+ // to distinguish from other possible tokens
+ if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
+ {
+ // "Node test that matches either NCName:* or QName was expected."
+ error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
+ }
}
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
@@ -2025,6 +2131,12 @@
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
+ final int RELATIVE_PATH_NOT_PERMITTED = 0;
+ final int RELATIVE_PATH_PERMITTED = 1;
+ final int RELATIVE_PATH_REQUIRED = 2;
+
+ int relativePathStatus = RELATIVE_PATH_NOT_PERMITTED;
+
appendOp(2, OpCodes.OP_LOCATIONPATHPATTERN);
if (lookahead('(', 1)
@@ -2033,17 +2145,27 @@
{
IdKeyPattern();
- if (tokenIs('/') && lookahead('/', 1))
+ if (tokenIs('/'))
{
- appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
+ nextToken();
+
+ if (tokenIs('/'))
+ {
+ appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
+
+ nextToken();
+ }
+ else
+ {
+ appendOp(4, OpCodes.MATCH_IMMEDIATE_ANCESTOR);
+ }
// Tell how long the step is without the predicate
m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
OpCodes.NODETYPE_FUNCTEST;
- nextToken();
- nextToken();
+ relativePathStatus = RELATIVE_PATH_REQUIRED;
}
}
else if (tokenIs('/'))
@@ -2057,12 +2179,17 @@
// of a '//' pattern, and so will cause 'a' to be matched when it has
// any ancestor that is 'x'.
nextToken();
+
+ relativePathStatus = RELATIVE_PATH_REQUIRED;
}
else
{
appendOp(4, OpCodes.FROM_ROOT);
+
+ relativePathStatus = RELATIVE_PATH_PERMITTED;
}
+
// Tell how long the step is without the predicate
m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
@@ -2070,10 +2197,22 @@
nextToken();
}
+ else
+ {
+ relativePathStatus = RELATIVE_PATH_REQUIRED;
+ }
- if (!tokenIs('|') && (null != m_token))
+ if (relativePathStatus != RELATIVE_PATH_NOT_PERMITTED)
{
- RelativePathPattern();
+ if (!tokenIs('|') && (null != m_token))
+ {
+ RelativePathPattern();
+ }
+ else if (relativePathStatus == RELATIVE_PATH_REQUIRED)
+ {
+ // "A relative path pattern was expected."
+ error(XPATHErrorResources.ER_EXPECTED_REL_PATH_PATTERN, null);
+ }
}
// Terminate for safety.
@@ -2103,18 +2242,24 @@
* | RelativePathPattern '/' StepPattern
* | RelativePathPattern '//' StepPattern
*
- *
* @throws javax.xml.transform.TransformerException
*/
- protected void RelativePathPattern() throws
javax.xml.transform.TransformerException
+ protected void RelativePathPattern()
+ throws javax.xml.transform.TransformerException
{
- StepPattern();
+ // Caller will have consumed any '/' or '//' preceding the
+ // RelativePathPattern, so let StepPattern know it can't begin with a '/'
+ boolean trailingSlashConsumed = StepPattern(false);
while (tokenIs('/'))
{
nextToken();
- StepPattern();
+
+ // StepPattern() may consume first slash of pair in "a//b" while
+ // processing StepPattern "a". On next iteration, let StepPattern know
+ // that happened, so it doesn't match ill-formed patterns like "a///b".
+ trailingSlashConsumed = StepPattern(!trailingSlashConsumed);
}
}
@@ -2122,22 +2267,32 @@
*
* StepPattern ::= AbbreviatedNodeTestStep
*
+ * @param isLeadingSlashPermitted a boolean indicating whether a slash can
+ * appear at the start of this step
+ *
+ * @return boolean indicating whether a slash following the step was
consumed
*
* @throws javax.xml.transform.TransformerException
*/
- protected void StepPattern() throws
javax.xml.transform.TransformerException
+ protected boolean StepPattern(boolean isLeadingSlashPermitted)
+ throws javax.xml.transform.TransformerException
{
- AbbreviatedNodeTestStep();
+ return AbbreviatedNodeTestStep(isLeadingSlashPermitted);
}
/**
*
* AbbreviatedNodeTestStep ::= '@'? NodeTest Predicate
*
+ * @param isLeadingSlashPermitted a boolean indicating whether a slash can
+ * appear at the start of this step
+ *
+ * @return boolean indicating whether a slash following the step was
consumed
*
* @throws javax.xml.transform.TransformerException
*/
- protected void AbbreviatedNodeTestStep() throws
javax.xml.transform.TransformerException
+ protected boolean AbbreviatedNodeTestStep(boolean isLeadingSlashPermitted)
+ throws javax.xml.transform.TransformerException
{
int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
@@ -2163,6 +2318,7 @@
}
else if (tokenIs("child"))
{
+ matchTypePos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
appendOp(2, axesType);
@@ -2180,6 +2336,11 @@
}
else if (tokenIs('/'))
{
+ if (!isLeadingSlashPermitted)
+ {
+ // "A step was expected in the pattern, but '/' was encountered."
+ error(XPATHErrorResources.ER_EXPECTED_STEP_PATTERN, null);
+ }
axesType = OpCodes.MATCH_ANY_ANCESTOR;
appendOp(2, axesType);
@@ -2187,11 +2348,6 @@
}
else
{
- if (tokenIs('/'))
- {
- nextToken();
- }
-
matchTypePos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
@@ -2212,15 +2368,37 @@
Predicate();
}
+ boolean trailingSlashConsumed;
+
+ // For "a//b", where "a" is current step, we need to mark operation of
+ // current step as "MATCH_ANY_ANCESTOR". Then we'll consume the first
+ // slash and subsequent step will be treated as a
MATCH_IMMEDIATE_ANCESTOR
+ // (unless it too is followed by '//'.)
+ //
+ // %REVIEW% Following is what happens today, but I'm not sure that's
+ // %REVIEW% correct behaviour. Perhaps no valid case could be
constructed
+ // %REVIEW% where it would matter?
+ //
+ // If current step is on the attribute axis (e.g., "@x//b"), we won't
+ // change the current step, and let following step be marked as
+ // MATCH_ANY_ANCESTOR on next call instead.
if ((matchTypePos > -1) && tokenIs('/') && lookahead('/', 1))
{
m_ops.m_opMap[matchTypePos] = OpCodes.MATCH_ANY_ANCESTOR;
nextToken();
+
+ trailingSlashConsumed = true;
+ }
+ else
+ {
+ trailingSlashConsumed = false;
}
// Tell how long the entire step is.
m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
+
+ return trailingSlashConsumed;
}
}
1.15 +24 -0
xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.java
Index: XPATHErrorResources.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- XPATHErrorResources.java 26 Jun 2002 15:17:38 -0000 1.14
+++ XPATHErrorResources.java 27 Jun 2002 15:01:19 -0000 1.15
@@ -491,6 +491,30 @@
// Programmer's assertion in getNextStepPos: unknown stepType: {0}
public static final int ER_UNKNOWN_STEP = 94;
+
+ /** Problem with RelativeLocationPath */
+ public static final int ER_EXPECTED_REL_LOC_PATH = 95;
+
+
+ /** Problem with LocationPath */
+ public static final int ER_EXPECTED_LOC_PATH = 96;
+
+
+ /** Problem with Step */
+ public static final int ER_EXPECTED_LOC_STEP = 97;
+
+
+ /** Problem with NodeTest */
+ public static final int ER_EXPECTED_NODE_TEST = 98;
+
+
+ /** Expected step pattern */
+ public static final int ER_EXPECTED_STEP_PATTERN = 99;
+
+
+ /** Expected relative path pattern */
+ public static final int ER_EXPECTED_REL_PATH_PATTERN = 100;
+
1.5 +12 -0
xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.properties
Index: XPATHErrorResources.properties
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.properties,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- XPATHErrorResources.properties 26 Jun 2002 15:17:38 -0000 1.4
+++ XPATHErrorResources.properties 27 Jun 2002 15:01:19 -0000 1.5
@@ -194,6 +194,18 @@
ER0093={0} only allows {1} arguments
# ER_UNKNOWN_STEP
ER0094=Programmer's assertion in getNextStepPos: unknown stepType: {0}
+# ER_EXPECTED_REL_LOC_PATH
+ER0095=A relative location path was expected following the '/' or '//' token.
+# ER_EXPECTED_LOC_PATH
+ER0096=A location path was expected, but the following token was
encountered\u003a {0}
+# ER_EXPECTED_LOC_STEP
+ER0097=A location step was expected following the '/' or '//' token.
+# ER_EXPECTED_NODE_TEST
+ER0098=A node test that matches either NCName:* or QName was expected.
+# ER_EXPECTED_STEP_PATTERN
+ER0099=A step pattern was expected, but '/' was encountered.
+# ER_EXPECTED_REL_PATH_PATTERN
+ER00100=A relative path pattern was expected.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]