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 
50 #include <xalanc/XPath/XPath.hpp>
51 
52 
53 
54 namespace XALAN_CPP_NAMESPACE {
55 
56 
57 
58 class 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 {
68 public:
69 
70  typedef XalanMap<XalanDOMString,
72 
74 
76 
77  XPathProcessorImpl(MemoryManager& theManager XALAN_DEFAULT_MEMMGR);
78 
79  virtual
81 
82 
83  static XPathProcessorImpl*
84  create(MemoryManager& theManager);
85  // These are inherited from XPathProcessor...
86 
87  virtual void
89  XPath& pathObj,
90  XPathConstructionContext& constructionContext,
91  const XalanDOMString& expression,
92  const PrefixResolver& resolver,
93  const Locator* locator = 0,
94  bool allowVariableReferences = true,
95  bool allowKeyFunction = true);
96 
97  virtual void
99  XPath& pathObj,
100  XPathConstructionContext& constructionContext,
101  const XalanDOMString& expression,
102  const PrefixResolver& resolver,
103  const Locator* locator = 0,
104  bool allowVariableReferences = true,
105  bool allowKeyFunction = true);
106 
107 private:
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,
131  t_size_type startSubstring,
132  t_size_type posOfNSSep,
133  t_size_type posOfScan);
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(
168  XalanDOMChar c,
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,
297  XalanDOMChar theToken1,
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 
705 private:
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...
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)
static XPathProcessorImpl * create(MemoryManager &theManager)
XalanVector< bool > BoolVectorType
Xalan implementation of a hashtable.
Definition: XalanMap.hpp:187
size_t size_type
Definition: XalanMap.hpp:46