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
88  initXPath(
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
98  initMatchPattern(
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
xalanc::XPathConstructionContext
Definition: XPathConstructionContext.hpp:60
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::XPathProcessorImpl::StringToStringMapType
XalanMap< XalanDOMString, const XalanDOMString * > StringToStringMapType
Definition: XPathProcessorImpl.hpp:71
xalanc::XPathProcessorImpl::BoolVectorType
XalanVector< bool > BoolVectorType
Definition: XPathProcessorImpl.hpp:73
XalanDOMString.hpp
xalanc::XalanVector< bool >
xalanc::XPath
Definition: XPath.hpp:67
xalanc::size_type
size_t size_type
Definition: XalanMap.hpp:46
XALAN_DEFAULT_MEMMGR
#define XALAN_DEFAULT_MEMMGR
Definition: XalanMemoryManagement.hpp:516
XalanVector.hpp
XALAN_XPATH_EXPORT
#define XALAN_XPATH_EXPORT
Definition: XPathDefinitions.hpp:35
XalanMessageLoader.hpp
XPathProcessor.hpp
xalanc::XPathProcessorImpl
The XPathProcessorImpl class responsibilities include tokenizing and parsing the XPath expression,...
Definition: XPathProcessorImpl.hpp:66
xalanc::XPathProcessorImpl::t_size_type
XalanDOMString::size_type t_size_type
Definition: XPathProcessorImpl.hpp:75
xalanc::PrefixResolver
This class defines an interface for classes that resolve namespace prefixes to their URIs.
Definition: PrefixResolver.hpp:39
xalanc::XPathProcessor
Definition: XPathProcessor.hpp:56
xalanc::XalanMap
Xalan implementation of a hashtable.
Definition: XalanMap.hpp:186
XPath.hpp
XalanMap.hpp
xalanc::XalanDOMString::size_type
XalanSize_t size_type
Definition: XalanDOMString.hpp:57
xalanc::XalanDOMString
Definition: XalanDOMString.hpp:45
xalanc::XPathExpression::eOpCodes
eOpCodes
List of operations codes.
Definition: XPathExpression.hpp:104
XPathDefinitions.hpp