Xalan-C++ API Reference 1.12.0
XPathProcessorImpl.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18#if !defined(XPATHPROCESSORIMPL_HEADER_GUARD_1357924680)
19#define XPATHPROCESSORIMPL_HEADER_GUARD_1357924680
20
21
22
23// Base header file. Must be first.
25
26
27
28#include <cstdlib>
29
30
31
33
34
35
38
39
40
42
43
44
45// Base class header file...
47
48
49
51
52
53
54namespace XALAN_CPP_NAMESPACE {
55
56
57
58class XalanNode;
59
60
61
62/**
63 * The XPathProcessorImpl class responsibilities include tokenizing and
64 * parsing the XPath expression, and acting as a general interface to XPaths.
65 */
67{
68public:
69
72
74
76
78
79 virtual
81
82
83 static XPathProcessorImpl*
84 create(MemoryManager& theManager);
85 // These are inherited from XPathProcessor...
86
87 virtual void
93 const Locator* locator = 0,
94 bool allowVariableReferences = true,
95 bool allowKeyFunction = true);
96
97 virtual void
103 const Locator* locator = 0,
104 bool allowVariableReferences = true,
105 bool allowKeyFunction = true);
106
107private:
108
109 /**
110 * Walk through the expression and build a token queue, and a map of the
111 * top-level elements.
112 *
113 * @param pat XSLT Expression.
114 */
115 void
116 tokenize(const XalanDOMString& pat);
117
118 void
119 addToTokenQueue(const XalanDOMString& s) const;
120
121 void
122 replaceTokenWithNamespaceToken() const;
123
124 /**
125 * When a separator token is found, see if there's a element name or the
126 * like to map.
127 */
129 mapNSTokens(
130 const XalanDOMString& pat,
134
135 /**
136 * Check if m_token==s. If m_token is null, this won't throw
137 * an exception, instead it just returns false (or true
138 * if s is also null).
139 */
140 bool
141 tokenIs(const XalanDOMString& s) const;
142
143 /**
144 * Check if m_token==s. If m_token is null, this won't throw
145 * an exception, instead it just returns false (or true
146 * if s is also null).
147 */
148 bool
149 tokenIs(const XalanDOMChar* s) const;
150
151 /**
152 * Check if m_token==s. If m_token is null, this won't throw
153 * an exception, instead it just returns false (or true
154 * if s is also null).
155 */
156 bool
157 tokenIs(XalanDOMChar c) const;
158
159 /**
160 * Lookahead of the current token in order to
161 * make a branching decision.
162 * @param s the string to compare it to.
163 * @param n number of tokens to lookahead. Must be
164 * greater than 1.
165 */
166 bool
167 lookahead(
169 int n) const;
170
171 /**
172 * Lookahead of the current token in order to
173 * make a branching decision.
174 * @param s the string to compare it to.
175 * @param n number of tokens to lookahead. Must be
176 * greater than 1.
177 */
178 bool
179 lookahead(
180 const XalanDOMChar* s,
181 int n) const;
182
183 /**
184 * Lookahead of the current token in order to
185 * make a branching decision.
186 * @param s the string to compare it to.
187 * @param n number of tokens to lookahead. Must be
188 * greater than 1.
189 */
190 bool
191 lookahead(
192 const XalanDOMString& s,
193 int n) const;
194
195 /**
196 * Lookbehind the first character of the current token in order to
197 * make a branching decision.
198 * @param c the character to compare it to.
199 * @param n number of tokens to lookbehind. Must be
200 * greater than 1. Note that the lookbehind terminates
201 * at either the beginning of the string or on a '|'
202 * character. Because of this, this method should only
203 * be used for pattern matching.
204 */
205 bool
206 lookbehind(
207 char c,
208 int n) const;
209
210 /**
211 * look behind the current token in order to
212 * see if there is a useable token.
213 * @param n number of tokens to lookahead. Must be
214 * greater than 1. Note that the lookbehind terminates
215 * at either the beginning of the string or on a '|'
216 * character. Because of this, this method should only
217 * be used for pattern matching.
218 * @return true if lookbehind has a token, false otherwise.
219 */
220 bool
221 lookbehindHasToken(int n) const;
222
223 /**
224 * Retrieve the next token from the command and
225 * store it in m_token string.
226 */
227 bool
228 nextToken();
229
230 /**
231 * Retrieve the next token from the command and
232 * store it in m_token string.
233 */
234 const XalanDOMString&
235 getTokenRelative(int theOffset) const;
236
237 /**
238 * Retrieve the previous token from the command and
239 * store it in m_token string.
240 */
241 void
242 prevToken();
243
244 /**
245 * Consume an expected token, throwing an exception if it
246 * isn't there.
247 */
248 void
249 consumeExpected(XalanDOMChar expected);
250
251 bool
252 isCurrentLiteral() const;
253
254 /**
255 * Determine if the token is an axis
256 *
257 * @param theToken The token to test
258 * @return true if the token is a valid axis, false if not.
259 */
260 static bool
261 isAxis(const XalanDOMString& theToken);
262
263 /**
264 * Determine if the token could be a node test
265 *
266 * @param theToken The token to test
267 * @return true if the token is a valid node test, false if not.
268 */
269 static bool
270 isNodeTest(const XalanDOMString& theToken);
271
272 /**
273 * Throw an exception using the provided message text.
274 */
275 void
276 error(const XalanDOMString& msg) const;
277
278 /**
279 * Throw an exception using the provided message text.
280 */
281 void
282 error(XalanMessages::Codes theCode) const;
283
284 void
285 error(
286 XalanMessages::Codes theCode,
287 const XalanDOMString& theToken) const;
288
289 void
290 error(
291 XalanMessages::Codes theCode,
292 const XalanDOMChar* theToken) const;
293
294 void
295 error(
296 XalanMessages::Codes theCode,
298 const XalanDOMString& theToken2) const;
299
300 /**
301 * Given a string, return the corresponding token.
302 */
304 getFunctionToken(const XalanDOMString& key)
305 {
306 return searchTable(s_functionTable, s_functionTableSize, key).m_opCode;
307 }
308
309 /**
310 * Given a string, return the corresponding token.
311 */
313 getNodeTypeToken(const XalanDOMString& key)
314 {
315 return searchTable(s_nodeTypeTable, s_nodeTypeTableSize, key).m_opCode;
316 }
317
318 /**
319 * Given a string, return the corresponding token.
320 */
321 static XPathExpression::eOpCodes
322 getAxisToken(const XalanDOMString& key)
323 {
324 return searchTable(s_axisTable, s_axisTableSize, key).m_opCode;
325 }
326
327 /**
328 *
329 * --------------------------------------------------------------------------------
330 Expr ::= OrExpr
331 * --------------------------------------------------------------------------------
332 */
333 void
334 Expr();
335
336
337 /**
338 *
339 * --------------------------------------------------------------------------------
340 OrExpr ::= AndExpr
341 | OrExpr 'or' AndExpr
342 * --------------------------------------------------------------------------------
343 */
344 void
345 OrExpr();
346
347 /**
348 *
349 * --------------------------------------------------------------------------------
350 AndExpr ::= EqualityExpr
351 | AndExpr 'and' EqualityExpr
352 * --------------------------------------------------------------------------------
353 */
354 void
355 AndExpr() ;
356
357 /**
358 * XXXX.
359 * @returns an Object which is either a String, a Number, a Boolean, or a vector
360 * of nodes.
361 * --------------------------------------------------------------------------------
362 EqualityExpr ::= RelationalExpr
363 | EqualityExpr '=' RelationalExpr
364 * --------------------------------------------------------------------------------
365 */
366 int
367 EqualityExpr(int opCodePos = -1);
368
369 /**
370 * XXXX.
371 * @returns an Object which is either a String, a Number, a Boolean, or a vector
372 * of nodes.
373 * --------------------------------------------------------------------------------
374 RelationalExpr ::= AdditiveExpr
375 | RelationalExpr '<' AdditiveExpr
376 | RelationalExpr '>' AdditiveExpr
377 | RelationalExpr '<=' AdditiveExpr
378 | RelationalExpr '>=' AdditiveExpr
379 * --------------------------------------------------------------------------------
380 */
381 int
382 RelationalExpr(int opCodePos = -1);
383
384 /**
385 * XXXX.
386 * @returns an Object which is either a String, a Number, a Boolean, or a vector
387 * of nodes.
388 * --------------------------------------------------------------------------------
389 AdditiveExpr ::= MultiplicativeExpr
390 | AdditiveExpr '+' MultiplicativeExpr
391 | AdditiveExpr '-' MultiplicativeExpr
392 * --------------------------------------------------------------------------------
393 */
394 int
395 AdditiveExpr(int opCodePos = -1);
396
397 /**
398 * XXXX.
399 * @returns an Object which is either a String, a Number, a Boolean, or a vector
400 * of nodes.
401 * --------------------------------------------------------------------------------
402 MultiplicativeExpr ::= UnaryExpr
403 | MultiplicativeExpr MultiplyOperator UnaryExpr
404 | MultiplicativeExpr 'div' UnaryExpr
405 | MultiplicativeExpr 'mod' UnaryExpr
406 | MultiplicativeExpr 'quo' UnaryExpr
407 * --------------------------------------------------------------------------------
408 */
409 int
410 MultiplicativeExpr(int opCodePos = -1);
411
412 /**
413 * XXXX.
414 * @returns an Object which is either a String, a Number, a Boolean, or a vector
415 * of nodes.
416 * --------------------------------------------------------------------------------
417 UnaryExpr ::= UnionExpr
418 | '-' UnaryExpr
419 * --------------------------------------------------------------------------------
420 */
421 void
422 UnaryExpr();
423
424 /**
425 * The context of the right hand side expressions is the context of the
426 * left hand side expression. The results of the right hand side expressions
427 * are node sets. The result of the left hand side UnionExpr is the union
428 * of the results of the right hand side expressions.
429 *
430 * --------------------------------------------------------------------------------
431 UnionExpr ::= PathExpr
432 | UnionExpr '|' PathExpr
433 * --------------------------------------------------------------------------------
434 */
435 void
436 UnionExpr();
437
438 /**
439 *
440 * --------------------------------------------------------------------------------
441 PathExpr ::= LocationPath
442 | FilterExpr
443 | FilterExpr '/' RelativeLocationPath
444 | FilterExpr '//' RelativeLocationPath
445 * --------------------------------------------------------------------------------
446 * @exception XSLProcessorException thrown if the active ProblemListener and XMLParserLiaison decide
447 * the error condition is severe enough to halt processing.
448 */
449 void
450 PathExpr();
451
452 /**
453 *
454 * --------------------------------------------------------------------------------
455 FilterExpr ::= PrimaryExpr
456 | FilterExpr Predicate
457 * --------------------------------------------------------------------------------
458 * @exception XSLProcessorException thrown if the active ProblemListener and XMLParserLiaison decide
459 * the error condition is severe enough to halt processing.
460 */
461 void
462 FilterExpr();
463
464 /**
465 * --------------------------------------------------------------------------------
466 PrimaryExpr ::= VariableReference
467 | '(' Expr ')'
468 | Literal
469 | Number
470 | FunctionCall
471 * --------------------------------------------------------------------------------
472 */
473 void
474 PrimaryExpr();
475
476
477 /**
478 * --------------------------------------------------------------------------------
479 Argument ::= Expr
480 * --------------------------------------------------------------------------------
481 */
482 void
483 Argument();
484
485 /**
486 * --------------------------------------------------------------------------------
487 FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')'
488 * --------------------------------------------------------------------------------
489 */
490 void
491 FunctionCall();
492
493 void
494 FunctionPosition();
495
496 void
497 FunctionLast();
498
499 void
500 FunctionCount();
501
502 void
503 FunctionNot();
504
505 void
506 FunctionTrue();
507
508 void
509 FunctionFalse();
510
511 void
512 FunctionBoolean();
513
514 void
515 FunctionName(int opPos);
516
517 void
518 FunctionLocalName(int opPos);
519
520 void
521 FunctionNumber(int opPos);
522
523 void
524 FunctionFloor();
525
526 void
527 FunctionCeiling();
528
529 void
530 FunctionRound();
531
532 void
533 FunctionString(int opPos);
534
535 void
536 FunctionStringLength(int opPos);
537
538 void
539 FunctionSum();
540
541 void
542 FunctionNamespaceURI(int opPos);
543
544 /**
545 * --------------------------------------------------------------------------------
546 LocationPath ::= RelativeLocationPath
547 | AbsoluteLocationPath
548 * --------------------------------------------------------------------------------
549 */
550 void
551 LocationPath();
552
553 /**
554 * --------------------------------------------------------------------------------
555 RelativeLocationPath ::= Step
556 | RelativeLocationPath '/' Step
557 | AbbreviatedRelativeLocationPath
558 * --------------------------------------------------------------------------------
559 */
560 void
561 RelativeLocationPath();
562
563 /**
564 * --------------------------------------------------------------------------------
565 Step ::= Basis Predicate*
566 | AbbreviatedStep
567 */
568 void
569 Step();
570
571 /**
572 * --------------------------------------------------------------------------------
573 Basis ::= AxisName '::' NodeTest
574 | AbbreviatedBasis
575 */
576 void
577 Basis();
578
579 /**
580 * --------------------------------------------------------------------------------
581 Basis ::= AxisName '::' NodeTest
582 | AbbreviatedBasis
583 */
584 XPathExpression::eOpCodes
585 AxisName();
586
587 /**
588 * --------------------------------------------------------------------------------
589 NodeTest ::= WildcardName
590 | NodeType '(' ')'
591 | 'processing-instruction' '(' Literal ')'
592 */
593 int
594 NodeTest();
595
596 /**
597 * --------------------------------------------------------------------------------
598 Predicate ::= '[' PredicateExpr ']'
599 * --------------------------------------------------------------------------------
600 */
601 void
602 Predicate();
603
604 /**
605 *--------------------------------------------------------------------------------
606 PredicateExpr ::= Expr
607 *--------------------------------------------------------------------------------
608 */
609 void
610 PredicateExpr();
611
612 /**
613 * QName ::= (Prefix ':')? LocalPart
614 * Prefix ::= NCName
615 * LocalPart ::= NCName
616 */
617 void
618 QName();
619
620 /**
621 * NCName ::= (Letter | '_') (NCNameChar)*
622 * NCNameChar ::= Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
623 */
624 void
625 NCName();
626
627 /**
628 * The value of the Literal is the sequence of characters inside
629 * the " or ' characters>.
630 * --------------------------------------------------------------------------------
631 Literal ::= '"' [^"]* '"'
632 | "'" [^']* "'"
633 * --------------------------------------------------------------------------------
634 */
635 void
636 Literal();
637
638 /**
639 * --------------------------------------------------------------------------------
640 * Number ::= [0-9]+('.'[0-9]+)? | '.'[0-9]+
641 * --------------------------------------------------------------------------------
642 */
643 void
644 Number();
645
646 /**
647 * --------------------------------------------------------------------------------
648 Pattern ::= LocationPathPattern
649 | Pattern '|' LocationPathPattern
650 * --------------------------------------------------------------------------------
651 */
652 void
653 Pattern();
654
655 /**
656 *
657 * --------------------------------------------------------------------------------
658 LocationPathPattern ::= '/' RelativePathPattern?
659 | IdKeyPattern (('/' | '//') RelativePathPattern)?
660 | '//'? RelativePathPattern
661 * --------------------------------------------------------------------------------
662 */
663 void
664 LocationPathPattern();
665
666 /**
667 * --------------------------------------------------------------------------------
668 IdKeyPattern ::= 'id' '(' Literal ')'
669 | 'key' '(' Literal ',' Literal ')'
670 * (Also handle doc())
671 * --------------------------------------------------------------------------------
672 */
673 void
674 IdKeyPattern();
675
676 /**
677 * --------------------------------------------------------------------------------
678 RelativePathPattern ::= StepPattern
679 | RelativePathPattern '/' StepPattern
680 | RelativePathPattern '//' StepPattern
681 * --------------------------------------------------------------------------------
682 */
683 void
684 RelativePathPattern();
685
686 /**
687 * --------------------------------------------------------------------------------
688 StepPattern ::= AbbreviatedNodeTestStep
689 * --------------------------------------------------------------------------------
690 */
691 void
692 StepPattern();
693
694 /**
695 * --------------------------------------------------------------------------------
696 AbbreviatedNodeTestStep ::= '@'? NodeTest Predicate*
697 * --------------------------------------------------------------------------------
698 */
699 void
700 AbbreviatedNodeTestStep();
701
702 static bool
703 isValidFunction(const XalanDOMString& key);
704
705private:
706
707 int
708 FunctionCallArguments();
709
710 struct TableEntry
711 {
712 const XalanDOMChar* m_string;
713
714 XPathExpression::eOpCodes m_opCode;
715 };
716
717 typedef std::size_t size_type;
718
719 static const TableEntry&
720 searchTable(
721 const TableEntry theTable[],
722 size_type theTableSize,
723 const XalanDOMString& theString);
724
725 /**
726 * The current input token.
727 */
728 XalanDOMString m_token;
729
730 /**
731 * The first char in m_token, the theory being that this
732 * is an optimization because we won't have to do index
733 * into the string as often.
734 */
735 XalanDOMChar m_tokenChar;
736
737 /**
738 * A pointer to the current XPath.
739 */
740 XPath* m_xpath;
741
742 /**
743 * A pointer to the current XPathConstructionContext.
744 */
745 XPathConstructionContext* m_constructionContext;
746
747 /**
748 * A pointer to the current XPath's expression.
749 */
750 XPathExpression* m_expression;
751
752 /**
753 * A pointer to the current executionContext.
754 */
755 const PrefixResolver* m_prefixResolver;
756
757 bool m_requireLiterals;
758
759 bool m_isMatchPattern;
760
761 const Locator* m_locator;
762
763 BoolVectorType m_positionPredicateStack;
764
765 StringToStringMapType m_namespaces;
766
767 bool m_allowVariableReferences;
768
769 bool m_allowKeyFunction;
770
771 // Static stuff here...
772 static const XalanDOMString s_emptyString;
773
774 static const XalanDOMChar s_functionIDString[];
775
776 // This shouldn't really be here, since it's not part of the XPath standard,
777 // but rather a part ofthe XSLT standard.
778 static const XalanDOMChar s_functionKeyString[];
779
780 static const XalanDOMChar s_orString[];
781
782 static const XalanDOMChar s_andString[];
783
784 static const XalanDOMChar s_divString[];
785
786 static const XalanDOMChar s_modString[];
787
788 static const XalanDOMChar s_dotString[];
789
790 static const XalanDOMChar s_dotDotString[];
791
792 static const XalanDOMChar s_axisString[];
793
794 static const XalanDOMChar s_attributeString[];
795
796 static const XalanDOMChar s_childString[];
797
798 static const XalanDOMChar s_lastString[];
799
800 static const XalanDOMChar s_positionString[];
801
802 static const XalanDOMChar s_asteriskString[];
803
804 static const XalanDOMChar s_commentString[];
805
806 static const XalanDOMChar s_piString[];
807
808 static const XalanDOMChar s_nodeString[];
809
810 static const XalanDOMChar s_textString[];
811
812 static const XalanDOMChar s_ancestorString[];
813
814 static const XalanDOMChar s_ancestorOrSelfString[];
815
816 static const XalanDOMChar s_descendantString[];
817
818 static const XalanDOMChar s_descendantOrSelfString[];
819
820 static const XalanDOMChar s_followingString[];
821
822 static const XalanDOMChar s_followingSiblingString[];
823
824 static const XalanDOMChar s_parentString[];
825
826 static const XalanDOMChar s_precedingString[];
827
828 static const XalanDOMChar s_precedingSiblingString[];
829
830 static const XalanDOMChar s_selfString[];
831
832 static const XalanDOMChar s_namespaceString[];
833
834 static const TableEntry s_functionTable[];
835
836 static const size_type s_functionTableSize;
837
838 static const TableEntry s_nodeTypeTable[];
839
840 static const size_type s_nodeTypeTableSize;
841
842 static const TableEntry s_axisTable[];
843
844 static const size_type s_axisTableSize;
845
846 static const TableEntry s_dummyEntry;
847};
848
849
850
851}
852
853
854
855#endif // XPATHPROCESSORIMPL_HEADER_GUARD_1357924680
#define XALAN_XPATH_EXPORT
#define XALAN_DEFAULT_MEMMGR
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
This class defines an interface for classes that resolve namespace prefixes to their URIs.
eOpCodes
List of operations codes.
The XPathProcessorImpl class responsibilities include tokenizing and parsing the XPath expression,...
XalanMap< XalanDOMString, const XalanDOMString * > StringToStringMapType
virtual void initXPath(XPath &pathObj, XPathConstructionContext &constructionContext, const XalanDOMString &expression, const PrefixResolver &resolver, const Locator *locator=0, bool allowVariableReferences=true, bool allowKeyFunction=true)
Given a string, make an XPath object, in order that a parse doesn't have to be done each time the exp...
static XPathProcessorImpl * create(MemoryManager &theManager)
virtual void initMatchPattern(XPath &pathObj, XPathConstructionContext &constructionContext, const XalanDOMString &expression, const PrefixResolver &resolver, const Locator *locator=0, bool allowVariableReferences=true, bool allowKeyFunction=true)
Given a string, create an XSLT Match Pattern object.
XalanDOMString::size_type t_size_type
XPathProcessorImpl(MemoryManager &theManager XALAN_DEFAULT_MEMMGR)
XalanVector< bool > BoolVectorType
Xalan implementation of a hashtable.
Definition XalanMap.hpp:187
size_t size_type
Definition XalanMap.hpp:46