1 | /* |
---|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
---|
3 | * contributor license agreements. See the NOTICE file distributed with |
---|
4 | * this work for additional information regarding copyright ownership. |
---|
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
---|
6 | * (the "License"); you may not use this file except in compliance with |
---|
7 | * the License. You may obtain a copy of the License at |
---|
8 | * |
---|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
---|
10 | * |
---|
11 | * Unless required by applicable law or agreed to in writing, software |
---|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
---|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
---|
14 | * See the License for the specific language governing permissions and |
---|
15 | * limitations under the License. |
---|
16 | */ |
---|
17 | |
---|
18 | /* |
---|
19 | * $Id: XercesXPath.cpp 903997 2010-01-28 08:28:06Z borisk $ |
---|
20 | */ |
---|
21 | |
---|
22 | // --------------------------------------------------------------------------- |
---|
23 | // Includes |
---|
24 | // --------------------------------------------------------------------------- |
---|
25 | #include <xercesc/validators/schema/identity/XercesXPath.hpp> |
---|
26 | #include <xercesc/validators/schema/identity/XPathSymbols.hpp> |
---|
27 | #include <xercesc/validators/schema/identity/XPathException.hpp> |
---|
28 | #include <xercesc/validators/schema/NamespaceScope.hpp> |
---|
29 | #include <xercesc/util/StringPool.hpp> |
---|
30 | #include <xercesc/util/Janitor.hpp> |
---|
31 | #include <icxercesc/framework/XMLBuffer.hpp> |
---|
32 | #include <icxercesc/internal/XMLReader.hpp> |
---|
33 | #include <xercesc/util/RuntimeException.hpp> |
---|
34 | #include <xercesc/util/OutOfMemoryException.hpp> |
---|
35 | |
---|
36 | #include <xercesc/internal/XTemplateSerializer.hpp> |
---|
37 | |
---|
38 | XERCES_CPP_NAMESPACE_BEGIN |
---|
39 | |
---|
40 | |
---|
41 | // --------------------------------------------------------------------------- |
---|
42 | // Static data |
---|
43 | // --------------------------------------------------------------------------- |
---|
44 | const XMLByte XPathScanner::fASCIICharMap[128] = |
---|
45 | { |
---|
46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0, |
---|
47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
48 | 2, 3, 4, 1, 5, 1, 1, 4, 6, 7, 8, 9, 10, 11, 12, 13, |
---|
49 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 1, 16, 17, 18, 1, |
---|
50 | 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, |
---|
51 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 1, 22, 1, 23, |
---|
52 | 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, |
---|
53 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1, 24, 1, 1, 1 |
---|
54 | }; |
---|
55 | |
---|
56 | |
---|
57 | // --------------------------------------------------------------------------- |
---|
58 | // XercesNodeTest: Constructors and Destructor |
---|
59 | // --------------------------------------------------------------------------- |
---|
60 | XercesNodeTest::XercesNodeTest(const short aType, |
---|
61 | MemoryManager* const manager) |
---|
62 | : fType(aType) |
---|
63 | , fName(new (manager) QName(manager)) |
---|
64 | { |
---|
65 | } |
---|
66 | |
---|
67 | XercesNodeTest::XercesNodeTest(const QName* const qName) |
---|
68 | : fType(NodeType_QNAME) |
---|
69 | , fName(new (qName->getMemoryManager()) QName(*qName)) |
---|
70 | { |
---|
71 | } |
---|
72 | |
---|
73 | XercesNodeTest::XercesNodeTest(const XMLCh* const prefix, |
---|
74 | const unsigned int uriId, |
---|
75 | MemoryManager* const manager) |
---|
76 | : fType(NodeType_NAMESPACE) |
---|
77 | , fName(new (manager) QName(manager)) |
---|
78 | { |
---|
79 | fName->setURI(uriId); |
---|
80 | fName->setPrefix(prefix); |
---|
81 | } |
---|
82 | |
---|
83 | XercesNodeTest::XercesNodeTest(const XercesNodeTest& other) |
---|
84 | : XSerializable(other) |
---|
85 | , XMemory(other) |
---|
86 | , fType(other.fType) |
---|
87 | , fName(new ((other.fName)->getMemoryManager()) QName(*other.fName)) |
---|
88 | { |
---|
89 | } |
---|
90 | |
---|
91 | /*** |
---|
92 | * Support for Serialization/De-serialization |
---|
93 | ***/ |
---|
94 | |
---|
95 | IMPL_XSERIALIZABLE_TOCREATE(XercesNodeTest) |
---|
96 | |
---|
97 | void XercesNodeTest::serialize(XSerializeEngine& serEng) |
---|
98 | { |
---|
99 | |
---|
100 | if (serEng.isStoring()) |
---|
101 | { |
---|
102 | serEng<<fType; |
---|
103 | serEng<<fName; |
---|
104 | } |
---|
105 | else |
---|
106 | { |
---|
107 | serEng>>fType; |
---|
108 | serEng>>fName; |
---|
109 | } |
---|
110 | } |
---|
111 | |
---|
112 | XercesNodeTest::XercesNodeTest(MemoryManager* const) |
---|
113 | :fType(NodeType_UNKNOWN) |
---|
114 | ,fName(0) |
---|
115 | { |
---|
116 | } |
---|
117 | |
---|
118 | // --------------------------------------------------------------------------- |
---|
119 | // XercesNodeTest: Operators |
---|
120 | // --------------------------------------------------------------------------- |
---|
121 | XercesNodeTest& XercesNodeTest::operator=(const XercesNodeTest& other) |
---|
122 | { |
---|
123 | if (this == &other) |
---|
124 | return *this; |
---|
125 | |
---|
126 | fType = other.fType; |
---|
127 | fName->setValues(*(other.fName)); |
---|
128 | return *this; |
---|
129 | } |
---|
130 | |
---|
131 | bool XercesNodeTest::operator ==(const XercesNodeTest& other) const { |
---|
132 | |
---|
133 | if (this == &other) |
---|
134 | return true; |
---|
135 | |
---|
136 | if (fType != other.fType) |
---|
137 | return false; |
---|
138 | |
---|
139 | return (*fName == *(other.fName)); |
---|
140 | } |
---|
141 | |
---|
142 | |
---|
143 | bool XercesNodeTest::operator !=(const XercesNodeTest& other) const { |
---|
144 | |
---|
145 | return !operator==(other); |
---|
146 | } |
---|
147 | |
---|
148 | // --------------------------------------------------------------------------- |
---|
149 | // XercesStep: Constructors and Destructor |
---|
150 | // --------------------------------------------------------------------------- |
---|
151 | XercesStep::XercesStep(const unsigned short axisType, XercesNodeTest* const nodeTest) |
---|
152 | : fAxisType(axisType) |
---|
153 | , fNodeTest(nodeTest) |
---|
154 | { |
---|
155 | } |
---|
156 | |
---|
157 | XercesStep::XercesStep(const XercesStep& other) |
---|
158 | : XSerializable(other) |
---|
159 | , XMemory(other) |
---|
160 | , fAxisType(other.fAxisType) |
---|
161 | , fNodeTest(0) |
---|
162 | { |
---|
163 | fNodeTest = new (other.fNodeTest->getName()->getMemoryManager()) XercesNodeTest(*(other.fNodeTest)); |
---|
164 | } |
---|
165 | |
---|
166 | |
---|
167 | // --------------------------------------------------------------------------- |
---|
168 | // XercesStep: Operators |
---|
169 | // --------------------------------------------------------------------------- |
---|
170 | XercesStep& XercesStep::operator=(const XercesStep& other) |
---|
171 | { |
---|
172 | if (this == &other) |
---|
173 | return *this; |
---|
174 | |
---|
175 | fAxisType = other.fAxisType; |
---|
176 | *fNodeTest = *(other.fNodeTest); |
---|
177 | return *this; |
---|
178 | } |
---|
179 | |
---|
180 | bool XercesStep::operator==(const XercesStep& other) const { |
---|
181 | |
---|
182 | if (this == &other) |
---|
183 | return true; |
---|
184 | |
---|
185 | if (fAxisType != other.fAxisType) |
---|
186 | return false; |
---|
187 | |
---|
188 | if (fAxisType == XercesStep::AxisType_CHILD || |
---|
189 | fAxisType == XercesStep::AxisType_ATTRIBUTE) { |
---|
190 | return (*fNodeTest == *(other.fNodeTest)); |
---|
191 | } |
---|
192 | |
---|
193 | return true; |
---|
194 | } |
---|
195 | |
---|
196 | bool XercesStep::operator!=(const XercesStep& other) const { |
---|
197 | |
---|
198 | return !operator==(other); |
---|
199 | } |
---|
200 | |
---|
201 | /*** |
---|
202 | * Support for Serialization/De-serialization |
---|
203 | ***/ |
---|
204 | |
---|
205 | IMPL_XSERIALIZABLE_TOCREATE(XercesStep) |
---|
206 | |
---|
207 | void XercesStep::serialize(XSerializeEngine& serEng) |
---|
208 | { |
---|
209 | if (serEng.isStoring()) |
---|
210 | { |
---|
211 | serEng<<(int)fAxisType; |
---|
212 | serEng<<fNodeTest; |
---|
213 | } |
---|
214 | else |
---|
215 | { |
---|
216 | int i; |
---|
217 | serEng>>i; |
---|
218 | fAxisType = (unsigned short) i; |
---|
219 | |
---|
220 | serEng>>fNodeTest; |
---|
221 | } |
---|
222 | } |
---|
223 | |
---|
224 | XercesStep::XercesStep(MemoryManager* const) |
---|
225 | :fAxisType(AxisType_UNKNOWN) |
---|
226 | ,fNodeTest(0) |
---|
227 | { |
---|
228 | } |
---|
229 | |
---|
230 | // --------------------------------------------------------------------------- |
---|
231 | // XercesLocationPath: Constructors and Destructor |
---|
232 | // --------------------------------------------------------------------------- |
---|
233 | XercesLocationPath::XercesLocationPath(RefVectorOf<XercesStep>* const steps) |
---|
234 | : fSteps(steps) |
---|
235 | { |
---|
236 | } |
---|
237 | |
---|
238 | // --------------------------------------------------------------------------- |
---|
239 | // XercesLocationPath: Operators |
---|
240 | // --------------------------------------------------------------------------- |
---|
241 | bool XercesLocationPath::operator==(const XercesLocationPath& other) const { |
---|
242 | |
---|
243 | XMLSize_t stepsSize = fSteps->size(); |
---|
244 | |
---|
245 | if (stepsSize != other.fSteps->size()) |
---|
246 | return false; |
---|
247 | |
---|
248 | for (XMLSize_t i=0; i < stepsSize; i++) { |
---|
249 | if (*(fSteps->elementAt(i)) != *(other.fSteps->elementAt(i))) |
---|
250 | return false; |
---|
251 | } |
---|
252 | |
---|
253 | return true; |
---|
254 | } |
---|
255 | |
---|
256 | bool XercesLocationPath::operator!=(const XercesLocationPath& other) const { |
---|
257 | |
---|
258 | return !operator==(other); |
---|
259 | } |
---|
260 | |
---|
261 | /*** |
---|
262 | * Support for Serialization/De-serialization |
---|
263 | ***/ |
---|
264 | |
---|
265 | IMPL_XSERIALIZABLE_TOCREATE(XercesLocationPath) |
---|
266 | |
---|
267 | void XercesLocationPath::serialize(XSerializeEngine& serEng) |
---|
268 | { |
---|
269 | if (serEng.isStoring()) |
---|
270 | { |
---|
271 | /*** |
---|
272 | * Serialize RefVectorOf<XercesStep>* fSteps; |
---|
273 | ***/ |
---|
274 | XTemplateSerializer::storeObject(fSteps, serEng); |
---|
275 | } |
---|
276 | else |
---|
277 | { |
---|
278 | /*** |
---|
279 | * Deserialize RefVectorOf<XercesStep>* fSteps; |
---|
280 | ***/ |
---|
281 | XTemplateSerializer::loadObject(&fSteps, 8, true, serEng); |
---|
282 | } |
---|
283 | } |
---|
284 | |
---|
285 | XercesLocationPath::XercesLocationPath(MemoryManager* const) |
---|
286 | :fSteps(0) |
---|
287 | { |
---|
288 | } |
---|
289 | |
---|
290 | typedef JanitorMemFunCall<XercesXPath> CleanupType; |
---|
291 | |
---|
292 | // --------------------------------------------------------------------------- |
---|
293 | // XercesPath: Constructors and Destructor |
---|
294 | // --------------------------------------------------------------------------- |
---|
295 | XercesXPath::XercesXPath(const XMLCh* const xpathExpr, |
---|
296 | XMLStringPool* const stringPool, |
---|
297 | XercesNamespaceResolver* const scopeContext, |
---|
298 | const unsigned int emptyNamespaceId, |
---|
299 | const bool isSelector, |
---|
300 | MemoryManager* const manager) |
---|
301 | : fEmptyNamespaceId(emptyNamespaceId) |
---|
302 | , fExpression(0) |
---|
303 | , fLocationPaths(0) |
---|
304 | , fMemoryManager(manager) |
---|
305 | { |
---|
306 | CleanupType cleanup(this, &XercesXPath::cleanUp); |
---|
307 | |
---|
308 | try |
---|
309 | { |
---|
310 | fExpression = XMLString::replicate(xpathExpr, fMemoryManager); |
---|
311 | parseExpression(stringPool, scopeContext); |
---|
312 | |
---|
313 | if (isSelector) { |
---|
314 | checkForSelectedAttributes(); |
---|
315 | } |
---|
316 | } |
---|
317 | catch(const OutOfMemoryException&) |
---|
318 | { |
---|
319 | cleanup.release(); |
---|
320 | |
---|
321 | throw; |
---|
322 | } |
---|
323 | |
---|
324 | cleanup.release(); |
---|
325 | } |
---|
326 | |
---|
327 | XercesXPath::~XercesXPath() { |
---|
328 | cleanUp(); |
---|
329 | } |
---|
330 | |
---|
331 | |
---|
332 | // --------------------------------------------------------------------------- |
---|
333 | // XercesXPath: Operators |
---|
334 | // --------------------------------------------------------------------------- |
---|
335 | bool XercesXPath::operator==(const XercesXPath& other) const { |
---|
336 | |
---|
337 | XMLSize_t locPathSize = fLocationPaths->size(); |
---|
338 | |
---|
339 | if (locPathSize != other.fLocationPaths->size()) |
---|
340 | return false; |
---|
341 | |
---|
342 | for (XMLSize_t i=0; i < locPathSize; i++) { |
---|
343 | if (*(fLocationPaths->elementAt(i)) != *(other.fLocationPaths->elementAt(i))) |
---|
344 | return false; |
---|
345 | } |
---|
346 | |
---|
347 | return true; |
---|
348 | } |
---|
349 | |
---|
350 | bool XercesXPath::operator!=(const XercesXPath& other) const { |
---|
351 | |
---|
352 | return !operator==(other); |
---|
353 | } |
---|
354 | |
---|
355 | // --------------------------------------------------------------------------- |
---|
356 | // XercesPath: Helper methods |
---|
357 | // --------------------------------------------------------------------------- |
---|
358 | void XercesXPath::cleanUp() { |
---|
359 | |
---|
360 | fMemoryManager->deallocate(fExpression);//delete [] fExpression; |
---|
361 | delete fLocationPaths; |
---|
362 | } |
---|
363 | |
---|
364 | void XercesXPath::checkForSelectedAttributes() { |
---|
365 | |
---|
366 | // verify that an attribute is not selected |
---|
367 | XMLSize_t locSize = (fLocationPaths) ? fLocationPaths->size() : 0; |
---|
368 | |
---|
369 | for (XMLSize_t i = 0; i < locSize; i++) { |
---|
370 | |
---|
371 | XercesLocationPath* locPath = fLocationPaths->elementAt(i); |
---|
372 | XMLSize_t stepSize = locPath->getStepSize(); |
---|
373 | |
---|
374 | if (stepSize) { |
---|
375 | if (locPath->getStep(stepSize - 1)->getAxisType() == XercesStep::AxisType_ATTRIBUTE) { |
---|
376 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoAttrSelector, fMemoryManager); |
---|
377 | } |
---|
378 | } |
---|
379 | } |
---|
380 | } |
---|
381 | |
---|
382 | void XercesXPath::parseExpression(XMLStringPool* const stringPool, |
---|
383 | XercesNamespaceResolver* const scopeContext) { |
---|
384 | |
---|
385 | XMLSize_t length = XMLString::stringLen(fExpression); |
---|
386 | |
---|
387 | if (!length) { |
---|
388 | return; |
---|
389 | } |
---|
390 | |
---|
391 | ValueVectorOf<int> tokens(16, fMemoryManager); |
---|
392 | XPathScannerForSchema scanner(stringPool); |
---|
393 | if(!scanner.scanExpression(fExpression, 0, length, &tokens)) |
---|
394 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_TokenNotSupported, fMemoryManager); |
---|
395 | |
---|
396 | bool firstTokenOfLocationPath=true; |
---|
397 | XMLSize_t tokenCount = tokens.size(); |
---|
398 | RefVectorOf<XercesStep>* stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager); |
---|
399 | Janitor<RefVectorOf<XercesStep> > janSteps(stepsVector); |
---|
400 | |
---|
401 | if (tokenCount) { |
---|
402 | fLocationPaths = new (fMemoryManager) RefVectorOf<XercesLocationPath>(8, true, fMemoryManager); |
---|
403 | } |
---|
404 | |
---|
405 | for (XMLSize_t i = 0; i < tokenCount; i++) { |
---|
406 | |
---|
407 | int aToken = tokens.elementAt(i); |
---|
408 | bool isNamespace=false; |
---|
409 | |
---|
410 | switch (aToken) { |
---|
411 | case XercesXPath::EXPRTOKEN_OPERATOR_UNION: |
---|
412 | { |
---|
413 | if (i == 0) { |
---|
414 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoUnionAtStart, fMemoryManager); |
---|
415 | } |
---|
416 | |
---|
417 | XMLSize_t stepsSize = stepsVector->size(); |
---|
418 | |
---|
419 | if (stepsSize == 0) { |
---|
420 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoMultipleUnion, fMemoryManager); |
---|
421 | } |
---|
422 | |
---|
423 | if(stepsVector->elementAt(0)->getAxisType()!=XercesStep::AxisType_SELF) |
---|
424 | { |
---|
425 | // prepend ./ |
---|
426 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); |
---|
427 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_SELF, nodeTest); |
---|
428 | stepsVector->insertElementAt(step, 0); |
---|
429 | } |
---|
430 | XercesLocationPath* newPath = new (fMemoryManager) XercesLocationPath(stepsVector); |
---|
431 | janSteps.orphan(); |
---|
432 | bool bFound=false; |
---|
433 | for(XMLSize_t i=0;i<fLocationPaths->size();i++) |
---|
434 | if((*(fLocationPaths->elementAt(i)))==(*newPath)) |
---|
435 | { |
---|
436 | bFound=true; |
---|
437 | break; |
---|
438 | } |
---|
439 | if(bFound) |
---|
440 | delete newPath; |
---|
441 | else |
---|
442 | fLocationPaths->addElement(newPath); |
---|
443 | stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager); |
---|
444 | janSteps.reset(stepsVector); |
---|
445 | firstTokenOfLocationPath = true; |
---|
446 | } |
---|
447 | break; |
---|
448 | case XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE: |
---|
449 | { |
---|
450 | // consume "::" token and drop through |
---|
451 | i++; |
---|
452 | } |
---|
453 | case XercesXPath::EXPRTOKEN_ATSIGN: |
---|
454 | { |
---|
455 | // consume QName token |
---|
456 | if (i == tokenCount - 1) { |
---|
457 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_MissingAttr, fMemoryManager); |
---|
458 | } |
---|
459 | |
---|
460 | aToken = tokens.elementAt(++i); |
---|
461 | |
---|
462 | if (aToken != XercesXPath::EXPRTOKEN_NAMETEST_QNAME |
---|
463 | && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_ANY |
---|
464 | && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE) { |
---|
465 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedToken1, fMemoryManager); |
---|
466 | } |
---|
467 | |
---|
468 | bool isNamespaceAtt=false; |
---|
469 | |
---|
470 | switch (aToken) { |
---|
471 | |
---|
472 | case XercesXPath::EXPRTOKEN_NAMETEST_ANY: |
---|
473 | { |
---|
474 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_WILDCARD, fMemoryManager); |
---|
475 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_ATTRIBUTE, nodeTest); |
---|
476 | stepsVector->addElement(step); |
---|
477 | break; |
---|
478 | } |
---|
479 | case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE: |
---|
480 | { |
---|
481 | isNamespaceAtt = true; |
---|
482 | } |
---|
483 | case XercesXPath::EXPRTOKEN_NAMETEST_QNAME: |
---|
484 | { |
---|
485 | aToken = tokens.elementAt(++i); |
---|
486 | |
---|
487 | const XMLCh* prefix = XMLUni::fgZeroLenString; |
---|
488 | unsigned int uri = fEmptyNamespaceId; |
---|
489 | |
---|
490 | if (scopeContext && aToken != -1) { |
---|
491 | |
---|
492 | prefix = stringPool->getValueForId(aToken); |
---|
493 | uri = scopeContext->getNamespaceForPrefix(prefix); |
---|
494 | } |
---|
495 | |
---|
496 | if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) { |
---|
497 | ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix, fMemoryManager); |
---|
498 | } |
---|
499 | |
---|
500 | if (isNamespaceAtt) { |
---|
501 | |
---|
502 | // build step |
---|
503 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager); |
---|
504 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_ATTRIBUTE, nodeTest); |
---|
505 | stepsVector->addElement(step); |
---|
506 | break; |
---|
507 | } |
---|
508 | |
---|
509 | aToken = tokens.elementAt(++i); |
---|
510 | |
---|
511 | const XMLCh* localPart = stringPool->getValueForId(aToken); |
---|
512 | QName aQName(prefix, localPart, uri, fMemoryManager); |
---|
513 | |
---|
514 | // build step |
---|
515 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName); |
---|
516 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_ATTRIBUTE, nodeTest); |
---|
517 | stepsVector->addElement(step); |
---|
518 | break; |
---|
519 | } |
---|
520 | } |
---|
521 | |
---|
522 | firstTokenOfLocationPath=false; |
---|
523 | break; |
---|
524 | } |
---|
525 | case XercesXPath::EXPRTOKEN_DOUBLE_COLON: |
---|
526 | { |
---|
527 | // should never have a bare double colon |
---|
528 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoDoubleColon, fMemoryManager); |
---|
529 | } |
---|
530 | case XercesXPath::EXPRTOKEN_AXISNAME_CHILD: |
---|
531 | { |
---|
532 | // consume "::" token and drop through |
---|
533 | i++; |
---|
534 | |
---|
535 | if (i == tokenCount - 1) { |
---|
536 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep1, fMemoryManager); |
---|
537 | } |
---|
538 | |
---|
539 | firstTokenOfLocationPath=false; |
---|
540 | break; |
---|
541 | } |
---|
542 | case XercesXPath::EXPRTOKEN_NAMETEST_ANY: |
---|
543 | { |
---|
544 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_WILDCARD, fMemoryManager); |
---|
545 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_CHILD, nodeTest); |
---|
546 | stepsVector->addElement(step); |
---|
547 | firstTokenOfLocationPath = false; |
---|
548 | break; |
---|
549 | } |
---|
550 | case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE: |
---|
551 | { |
---|
552 | isNamespace=true; |
---|
553 | } |
---|
554 | case XercesXPath::EXPRTOKEN_NAMETEST_QNAME: |
---|
555 | { |
---|
556 | // consume QName token |
---|
557 | aToken = tokens.elementAt(++i); |
---|
558 | |
---|
559 | const XMLCh* prefix = XMLUni::fgZeroLenString; |
---|
560 | unsigned int uri = fEmptyNamespaceId; |
---|
561 | |
---|
562 | if (scopeContext && aToken != -1) { |
---|
563 | |
---|
564 | prefix = stringPool->getValueForId(aToken); |
---|
565 | uri = scopeContext->getNamespaceForPrefix(prefix); |
---|
566 | } |
---|
567 | |
---|
568 | if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) { |
---|
569 | ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix, fMemoryManager); |
---|
570 | } |
---|
571 | |
---|
572 | if (isNamespace) { |
---|
573 | |
---|
574 | // build step |
---|
575 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager); |
---|
576 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_CHILD, nodeTest); |
---|
577 | stepsVector->addElement(step); |
---|
578 | break; |
---|
579 | } |
---|
580 | |
---|
581 | aToken = tokens.elementAt(++i); |
---|
582 | const XMLCh* localPart = stringPool->getValueForId(aToken); |
---|
583 | QName aQName(prefix, localPart, uri, fMemoryManager); |
---|
584 | |
---|
585 | // build step |
---|
586 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName); |
---|
587 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_CHILD, nodeTest); |
---|
588 | stepsVector->addElement(step); |
---|
589 | firstTokenOfLocationPath = false; |
---|
590 | break; |
---|
591 | } |
---|
592 | case XercesXPath::EXPRTOKEN_PERIOD: |
---|
593 | { |
---|
594 | // build step |
---|
595 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); |
---|
596 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_SELF, nodeTest); |
---|
597 | stepsVector->addElement(step); |
---|
598 | |
---|
599 | if (firstTokenOfLocationPath && i+1 < tokenCount) { |
---|
600 | |
---|
601 | aToken = tokens.elementAt(i+1); |
---|
602 | |
---|
603 | if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH){ |
---|
604 | |
---|
605 | if (++i == tokenCount - 1) { |
---|
606 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep2, fMemoryManager); |
---|
607 | } |
---|
608 | |
---|
609 | if (i+1 < tokenCount) { |
---|
610 | |
---|
611 | aToken = tokens.elementAt(i+1); |
---|
612 | |
---|
613 | if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH) { |
---|
614 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoForwardSlash, fMemoryManager); |
---|
615 | } |
---|
616 | } |
---|
617 | // build step |
---|
618 | nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); |
---|
619 | step = new (fMemoryManager) XercesStep(XercesStep::AxisType_DESCENDANT, nodeTest); |
---|
620 | stepsVector->addElement(step); |
---|
621 | } |
---|
622 | } |
---|
623 | firstTokenOfLocationPath=false; |
---|
624 | break; |
---|
625 | } |
---|
626 | case XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH: |
---|
627 | { |
---|
628 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoDoubleForwardSlash, fMemoryManager); |
---|
629 | } |
---|
630 | case XercesXPath::EXPRTOKEN_OPERATOR_SLASH: |
---|
631 | { |
---|
632 | if (i == 0) { |
---|
633 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoForwardSlashAtStart, fMemoryManager); |
---|
634 | } |
---|
635 | |
---|
636 | // keep on truckin' |
---|
637 | if (firstTokenOfLocationPath) { |
---|
638 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoSelectionOfRoot, fMemoryManager); |
---|
639 | } |
---|
640 | |
---|
641 | if (i == tokenCount - 1) { |
---|
642 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep3, fMemoryManager); |
---|
643 | } |
---|
644 | |
---|
645 | aToken = tokens.elementAt(i+1); |
---|
646 | if(aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH || aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH || aToken == XercesXPath::EXPRTOKEN_OPERATOR_UNION) |
---|
647 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep3, fMemoryManager); |
---|
648 | |
---|
649 | firstTokenOfLocationPath=false; |
---|
650 | break; |
---|
651 | } |
---|
652 | default: |
---|
653 | firstTokenOfLocationPath=false; |
---|
654 | } |
---|
655 | } |
---|
656 | |
---|
657 | XMLSize_t stepsSize = stepsVector->size(); |
---|
658 | |
---|
659 | if (stepsSize == 0) { |
---|
660 | if (!fLocationPaths || fLocationPaths->size() == 0) { |
---|
661 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_EmptyExpr, fMemoryManager); |
---|
662 | } |
---|
663 | else { |
---|
664 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoUnionAtEnd, fMemoryManager); |
---|
665 | } |
---|
666 | } |
---|
667 | |
---|
668 | if(stepsVector->elementAt(0)->getAxisType()!=XercesStep::AxisType_SELF) |
---|
669 | { |
---|
670 | // prepend ./ |
---|
671 | XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); |
---|
672 | XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_SELF, nodeTest); |
---|
673 | stepsVector->insertElementAt(step, 0); |
---|
674 | } |
---|
675 | XercesLocationPath* newPath = new (fMemoryManager) XercesLocationPath(stepsVector); |
---|
676 | janSteps.orphan(); |
---|
677 | bool bFound=false; |
---|
678 | for(XMLSize_t j=0;j<fLocationPaths->size();j++) |
---|
679 | if((*(fLocationPaths->elementAt(j)))==(*newPath)) |
---|
680 | { |
---|
681 | bFound=true; |
---|
682 | break; |
---|
683 | } |
---|
684 | if(bFound) |
---|
685 | delete newPath; |
---|
686 | else |
---|
687 | fLocationPaths->addElement(newPath); |
---|
688 | } |
---|
689 | |
---|
690 | /*** |
---|
691 | * Support for Serialization/De-serialization |
---|
692 | ***/ |
---|
693 | |
---|
694 | IMPL_XSERIALIZABLE_TOCREATE(XercesXPath) |
---|
695 | |
---|
696 | void XercesXPath::serialize(XSerializeEngine& serEng) |
---|
697 | { |
---|
698 | |
---|
699 | if (serEng.isStoring()) |
---|
700 | { |
---|
701 | serEng<<fEmptyNamespaceId; |
---|
702 | serEng.writeString(fExpression); |
---|
703 | |
---|
704 | /*** |
---|
705 | * Serialize RefVectorOf<XercesLocationPath>* fLocationPaths; |
---|
706 | ***/ |
---|
707 | XTemplateSerializer::storeObject(fLocationPaths, serEng); |
---|
708 | } |
---|
709 | else |
---|
710 | { |
---|
711 | serEng>>fEmptyNamespaceId; |
---|
712 | serEng.readString(fExpression); |
---|
713 | |
---|
714 | /*** |
---|
715 | * Deserialize RefVectorOf<XercesLocationPath>* fLocationPaths; |
---|
716 | ***/ |
---|
717 | XTemplateSerializer::loadObject(&fLocationPaths, 8, true, serEng); |
---|
718 | } |
---|
719 | } |
---|
720 | |
---|
721 | XercesXPath::XercesXPath(MemoryManager* const manager) |
---|
722 | :fEmptyNamespaceId(0) |
---|
723 | ,fExpression(0) |
---|
724 | ,fLocationPaths(0) |
---|
725 | ,fMemoryManager(manager) |
---|
726 | { |
---|
727 | } |
---|
728 | |
---|
729 | // --------------------------------------------------------------------------- |
---|
730 | // XPathScanner: Constructors and Destructor |
---|
731 | // --------------------------------------------------------------------------- |
---|
732 | XPathScanner::XPathScanner(XMLStringPool* const stringPool) |
---|
733 | : fAndSymbol (0) |
---|
734 | , fOrSymbol(0) |
---|
735 | , fModSymbol(0) |
---|
736 | , fDivSymbol(0) |
---|
737 | , fCommentSymbol(0) |
---|
738 | , fTextSymbol(0) |
---|
739 | , fPISymbol(0) |
---|
740 | , fNodeSymbol(0) |
---|
741 | , fAncestorSymbol(0) |
---|
742 | , fAncestorOrSelfSymbol(0) |
---|
743 | , fAttributeSymbol(0) |
---|
744 | , fChildSymbol(0) |
---|
745 | , fDescendantSymbol(0) |
---|
746 | , fDescendantOrSelfSymbol(0) |
---|
747 | , fFollowingSymbol(0) |
---|
748 | , fFollowingSiblingSymbol(0) |
---|
749 | , fNamespaceSymbol(0) |
---|
750 | , fParentSymbol(0) |
---|
751 | , fPrecedingSymbol(0) |
---|
752 | , fPrecedingSiblingSymbol(0) |
---|
753 | , fSelfSymbol(0) |
---|
754 | , fStringPool(stringPool) |
---|
755 | { |
---|
756 | init(); |
---|
757 | } |
---|
758 | |
---|
759 | // --------------------------------------------------------------------------- |
---|
760 | // XPathScanner: Helper methods |
---|
761 | // --------------------------------------------------------------------------- |
---|
762 | void XPathScanner::init() { |
---|
763 | |
---|
764 | fAndSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_AND); |
---|
765 | fOrSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_OR); |
---|
766 | fModSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_MOD); |
---|
767 | fDivSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DIV); |
---|
768 | fCommentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_COMMENT); |
---|
769 | fTextSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_TEXT); |
---|
770 | fPISymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PI); |
---|
771 | fNodeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NODE); |
---|
772 | fAncestorSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR); |
---|
773 | fAncestorOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR_OR_SELF); |
---|
774 | fAttributeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ATTRIBUTE); |
---|
775 | fChildSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_CHILD); |
---|
776 | fDescendantSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT); |
---|
777 | fDescendantOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT_OR_SELF); |
---|
778 | fFollowingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING); |
---|
779 | fFollowingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING_SIBLING); |
---|
780 | fNamespaceSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NAMESPACE); |
---|
781 | fParentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PARENT); |
---|
782 | fPrecedingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING); |
---|
783 | fPrecedingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING_SIBLING); |
---|
784 | fSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_SELF); |
---|
785 | } |
---|
786 | |
---|
787 | |
---|
788 | // --------------------------------------------------------------------------- |
---|
789 | // XPathScanner: Scan methods |
---|
790 | // --------------------------------------------------------------------------- |
---|
791 | bool XPathScanner::scanExpression(const XMLCh* const data, |
---|
792 | XMLSize_t currentOffset, |
---|
793 | const XMLSize_t endOffset, |
---|
794 | ValueVectorOf<int>* const tokens) { |
---|
795 | |
---|
796 | bool starIsMultiplyOperator = false; |
---|
797 | XMLSize_t nameOffset = 0; |
---|
798 | int nameHandle = -1; |
---|
799 | int prefixHandle = -1; |
---|
800 | XMLCh ch; |
---|
801 | XMLBuffer dataBuffer(128, tokens->getMemoryManager()); |
---|
802 | |
---|
803 | while (currentOffset != endOffset) { |
---|
804 | |
---|
805 | ch = data[currentOffset]; |
---|
806 | |
---|
807 | while (XMLChar1_0::isWhitespace(ch)) { |
---|
808 | |
---|
809 | if (++currentOffset == endOffset) { |
---|
810 | break; |
---|
811 | } |
---|
812 | |
---|
813 | ch = data[currentOffset]; |
---|
814 | } |
---|
815 | |
---|
816 | if (currentOffset == endOffset) { |
---|
817 | break; |
---|
818 | } |
---|
819 | // |
---|
820 | // [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::' |
---|
821 | // | NameTest | NodeType | Operator | FunctionName |
---|
822 | // | AxisName | Literal | Number | VariableReference |
---|
823 | // |
---|
824 | XMLByte chartype = (ch >= 0x80) ? (XMLByte)CHARTYPE_NONASCII : fASCIICharMap[ch]; |
---|
825 | |
---|
826 | switch (chartype) { |
---|
827 | case CHARTYPE_OPEN_PAREN: // '(' |
---|
828 | addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN); |
---|
829 | starIsMultiplyOperator = false; |
---|
830 | ++currentOffset; |
---|
831 | break; |
---|
832 | case CHARTYPE_CLOSE_PAREN: // ')' |
---|
833 | addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_PAREN); |
---|
834 | starIsMultiplyOperator = true; |
---|
835 | ++currentOffset; |
---|
836 | break; |
---|
837 | case CHARTYPE_OPEN_BRACKET: // '[' |
---|
838 | addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_BRACKET); |
---|
839 | starIsMultiplyOperator = false; |
---|
840 | ++currentOffset; |
---|
841 | break; |
---|
842 | case CHARTYPE_CLOSE_BRACKET: // ']' |
---|
843 | addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_BRACKET); |
---|
844 | starIsMultiplyOperator = true; |
---|
845 | ++currentOffset; |
---|
846 | break; |
---|
847 | // |
---|
848 | // [30] Number ::= Digits ('.' Digits?)? | '.' Digits |
---|
849 | // ^^^^^^^^^^ |
---|
850 | // |
---|
851 | case CHARTYPE_PERIOD: // '.', '..' or '.' Digits |
---|
852 | if (currentOffset + 1 == endOffset) { |
---|
853 | addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); |
---|
854 | starIsMultiplyOperator = true; |
---|
855 | currentOffset++; |
---|
856 | break; |
---|
857 | } |
---|
858 | |
---|
859 | ch = data[currentOffset + 1]; |
---|
860 | |
---|
861 | if (ch == chPeriod) { // '..' |
---|
862 | addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_PERIOD); |
---|
863 | starIsMultiplyOperator = true; |
---|
864 | currentOffset += 2; |
---|
865 | } else if (ch >= chDigit_0 && ch <= chDigit_9) { |
---|
866 | addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER); |
---|
867 | starIsMultiplyOperator = true; |
---|
868 | currentOffset = scanNumber(data, endOffset, currentOffset, tokens); |
---|
869 | } else if (ch == chForwardSlash) { |
---|
870 | addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); |
---|
871 | starIsMultiplyOperator = true; |
---|
872 | currentOffset++; |
---|
873 | } else if (ch == chPipe) { // '|' |
---|
874 | addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); |
---|
875 | starIsMultiplyOperator = true; |
---|
876 | currentOffset++; |
---|
877 | } else if (XMLChar1_0::isWhitespace(ch)) { |
---|
878 | do { |
---|
879 | if (++currentOffset == endOffset) |
---|
880 | break; |
---|
881 | |
---|
882 | ch = data[currentOffset]; |
---|
883 | } while (XMLChar1_0::isWhitespace(ch)); |
---|
884 | |
---|
885 | if (currentOffset == endOffset || ch == chPipe || ch == chForwardSlash) { |
---|
886 | addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); |
---|
887 | starIsMultiplyOperator = true; |
---|
888 | break; |
---|
889 | } |
---|
890 | } else { |
---|
891 | XMLCh str[2]= {ch, 0 }; |
---|
892 | ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_InvalidChar, str, tokens->getMemoryManager()); |
---|
893 | } |
---|
894 | |
---|
895 | break; |
---|
896 | case CHARTYPE_ATSIGN: // '@' |
---|
897 | addToken(tokens, XercesXPath::EXPRTOKEN_ATSIGN); |
---|
898 | starIsMultiplyOperator = false; |
---|
899 | ++currentOffset; |
---|
900 | break; |
---|
901 | case CHARTYPE_COMMA: // ',' |
---|
902 | addToken(tokens, XercesXPath::EXPRTOKEN_COMMA); |
---|
903 | starIsMultiplyOperator = false; |
---|
904 | ++currentOffset; |
---|
905 | break; |
---|
906 | case CHARTYPE_COLON: // '::' |
---|
907 | if (++currentOffset == endOffset) { |
---|
908 | return false; // REVISIT |
---|
909 | } |
---|
910 | ch = data[currentOffset]; |
---|
911 | |
---|
912 | if (ch != chColon) { |
---|
913 | return false; // REVISIT |
---|
914 | } |
---|
915 | addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON); |
---|
916 | starIsMultiplyOperator = false; |
---|
917 | ++currentOffset; |
---|
918 | break; |
---|
919 | case CHARTYPE_SLASH: // '/' and '//' |
---|
920 | if (++currentOffset == endOffset) { |
---|
921 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH); |
---|
922 | starIsMultiplyOperator = false; |
---|
923 | break; |
---|
924 | } |
---|
925 | |
---|
926 | ch = data[currentOffset]; |
---|
927 | |
---|
928 | if (ch == chForwardSlash) { // '//' |
---|
929 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH); |
---|
930 | starIsMultiplyOperator = false; |
---|
931 | ++currentOffset; |
---|
932 | } else { |
---|
933 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH); |
---|
934 | starIsMultiplyOperator = false; |
---|
935 | } |
---|
936 | break; |
---|
937 | case CHARTYPE_UNION: // '|' |
---|
938 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_UNION); |
---|
939 | starIsMultiplyOperator = false; |
---|
940 | ++currentOffset; |
---|
941 | break; |
---|
942 | case CHARTYPE_PLUS: // '+' |
---|
943 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_PLUS); |
---|
944 | starIsMultiplyOperator = false; |
---|
945 | ++currentOffset; |
---|
946 | break; |
---|
947 | case CHARTYPE_MINUS: // '-' |
---|
948 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MINUS); |
---|
949 | starIsMultiplyOperator = false; |
---|
950 | ++currentOffset; |
---|
951 | break; |
---|
952 | case CHARTYPE_EQUAL: // '=' |
---|
953 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_EQUAL); |
---|
954 | starIsMultiplyOperator = false; |
---|
955 | ++currentOffset; |
---|
956 | break; |
---|
957 | case CHARTYPE_EXCLAMATION: // '!=' |
---|
958 | if (++currentOffset == endOffset) { |
---|
959 | return false; // REVISIT |
---|
960 | } |
---|
961 | |
---|
962 | ch = data[currentOffset]; |
---|
963 | |
---|
964 | if (ch != chEqual) { |
---|
965 | return false; // REVISIT |
---|
966 | } |
---|
967 | |
---|
968 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_NOT_EQUAL); |
---|
969 | starIsMultiplyOperator = false; |
---|
970 | ++currentOffset; |
---|
971 | break; |
---|
972 | case CHARTYPE_LESS: // '<' and '<=' |
---|
973 | if (++currentOffset == endOffset) { |
---|
974 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS); |
---|
975 | starIsMultiplyOperator = false; |
---|
976 | break; |
---|
977 | } |
---|
978 | |
---|
979 | ch = data[currentOffset]; |
---|
980 | |
---|
981 | if (ch == chEqual) { // '<=' |
---|
982 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS_EQUAL); |
---|
983 | starIsMultiplyOperator = false; |
---|
984 | ++currentOffset; |
---|
985 | } else { |
---|
986 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS); |
---|
987 | starIsMultiplyOperator = false; |
---|
988 | } |
---|
989 | break; |
---|
990 | case CHARTYPE_GREATER: // '>' and '>=' |
---|
991 | if (++currentOffset == endOffset) { |
---|
992 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER); |
---|
993 | starIsMultiplyOperator = false; |
---|
994 | break; |
---|
995 | } |
---|
996 | |
---|
997 | ch = data[currentOffset]; |
---|
998 | |
---|
999 | if (ch == chEqual) { // '>=' |
---|
1000 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER_EQUAL); |
---|
1001 | starIsMultiplyOperator = false; |
---|
1002 | ++currentOffset; |
---|
1003 | } else { |
---|
1004 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER); |
---|
1005 | starIsMultiplyOperator = false; |
---|
1006 | } |
---|
1007 | break; |
---|
1008 | // |
---|
1009 | // [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'" |
---|
1010 | // |
---|
1011 | case CHARTYPE_QUOTE: // '\"' or '\'' |
---|
1012 | { |
---|
1013 | XMLCh qchar = ch; |
---|
1014 | if (++currentOffset == endOffset) { |
---|
1015 | return false; // REVISIT |
---|
1016 | } |
---|
1017 | |
---|
1018 | ch = data[currentOffset]; |
---|
1019 | |
---|
1020 | XMLSize_t litOffset = currentOffset; |
---|
1021 | while (ch != qchar) { |
---|
1022 | if (++currentOffset == endOffset) { |
---|
1023 | return false; // REVISIT |
---|
1024 | } |
---|
1025 | |
---|
1026 | ch = data[currentOffset]; |
---|
1027 | } |
---|
1028 | |
---|
1029 | addToken(tokens, XercesXPath::EXPRTOKEN_LITERAL); |
---|
1030 | starIsMultiplyOperator = true; |
---|
1031 | |
---|
1032 | dataBuffer.set(data + litOffset, currentOffset - litOffset); |
---|
1033 | tokens->addElement(fStringPool->addOrFind(dataBuffer.getRawBuffer())); |
---|
1034 | ++currentOffset; |
---|
1035 | break; |
---|
1036 | } |
---|
1037 | // |
---|
1038 | // [30] Number ::= Digits ('.' Digits?)? | '.' Digits |
---|
1039 | // [31] Digits ::= [0-9]+ |
---|
1040 | // |
---|
1041 | case CHARTYPE_DIGIT: |
---|
1042 | addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER); |
---|
1043 | starIsMultiplyOperator = true; |
---|
1044 | currentOffset = scanNumber(data, endOffset, currentOffset, tokens); |
---|
1045 | break; |
---|
1046 | // |
---|
1047 | // [36] VariableReference ::= '$' QName |
---|
1048 | // |
---|
1049 | case CHARTYPE_DOLLAR: |
---|
1050 | if (++currentOffset == endOffset) { |
---|
1051 | return false; // REVISIT |
---|
1052 | } |
---|
1053 | nameOffset = currentOffset; |
---|
1054 | currentOffset = scanNCName(data, endOffset, currentOffset); |
---|
1055 | |
---|
1056 | if (currentOffset == nameOffset) { |
---|
1057 | return false; // REVISIT |
---|
1058 | } |
---|
1059 | |
---|
1060 | if (currentOffset < endOffset) { |
---|
1061 | ch = data[currentOffset]; |
---|
1062 | } |
---|
1063 | else { |
---|
1064 | ch = 0; |
---|
1065 | } |
---|
1066 | |
---|
1067 | dataBuffer.set(data + nameOffset, currentOffset - nameOffset); |
---|
1068 | nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); |
---|
1069 | prefixHandle = -1; |
---|
1070 | |
---|
1071 | if (ch == chColon) { |
---|
1072 | |
---|
1073 | prefixHandle = nameHandle; |
---|
1074 | if (++currentOffset == endOffset) { |
---|
1075 | return false; // REVISIT |
---|
1076 | } |
---|
1077 | nameOffset = currentOffset; |
---|
1078 | currentOffset = scanNCName(data, endOffset, currentOffset); |
---|
1079 | |
---|
1080 | if (currentOffset == nameOffset) { |
---|
1081 | return false; // REVISIT |
---|
1082 | } |
---|
1083 | |
---|
1084 | dataBuffer.set(data + nameOffset, currentOffset - nameOffset); |
---|
1085 | nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); |
---|
1086 | } |
---|
1087 | addToken(tokens, XercesXPath::EXPRTOKEN_VARIABLE_REFERENCE); |
---|
1088 | starIsMultiplyOperator = true; |
---|
1089 | tokens->addElement(prefixHandle); |
---|
1090 | tokens->addElement(nameHandle); |
---|
1091 | break; |
---|
1092 | // |
---|
1093 | // [37] NameTest ::= '*' | NCName ':' '*' | QName |
---|
1094 | // [34] MultiplyOperator ::= '*' |
---|
1095 | // |
---|
1096 | case CHARTYPE_STAR: // '*' |
---|
1097 | // |
---|
1098 | // 3.7 Lexical Structure |
---|
1099 | // |
---|
1100 | // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or |
---|
1101 | // an Operator, then a * must be recognized as a MultiplyOperator. |
---|
1102 | // |
---|
1103 | // Otherwise, the token must not be recognized as a MultiplyOperator. |
---|
1104 | // |
---|
1105 | if (starIsMultiplyOperator) { |
---|
1106 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MULT); |
---|
1107 | starIsMultiplyOperator = false; |
---|
1108 | } else { |
---|
1109 | addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_ANY); |
---|
1110 | starIsMultiplyOperator = true; |
---|
1111 | } |
---|
1112 | |
---|
1113 | ++currentOffset; |
---|
1114 | break; |
---|
1115 | // |
---|
1116 | // NCName, QName and non-terminals |
---|
1117 | // |
---|
1118 | case CHARTYPE_NONASCII: // possibly a valid non-ascii 'Letter' (BaseChar | Ideographic) |
---|
1119 | case CHARTYPE_LETTER: |
---|
1120 | case CHARTYPE_UNDERSCORE: |
---|
1121 | { |
---|
1122 | // |
---|
1123 | // 3.7 Lexical Structure |
---|
1124 | // |
---|
1125 | // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or |
---|
1126 | // an Operator, then an NCName must be recognized as an OperatorName. |
---|
1127 | // |
---|
1128 | // If the character following an NCName (possibly after intervening ExprWhitespace) is (, |
---|
1129 | // then the token must be recognized as a NodeType or a FunctionName. |
---|
1130 | // |
---|
1131 | // If the two characters following an NCName (possibly after intervening ExprWhitespace) |
---|
1132 | // are ::, then the token must be recognized as an AxisName. |
---|
1133 | // |
---|
1134 | // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a |
---|
1135 | // FunctionName, or an AxisName. |
---|
1136 | // |
---|
1137 | // [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div' |
---|
1138 | // [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node' |
---|
1139 | // [35] FunctionName ::= QName - NodeType |
---|
1140 | // [6] AxisName ::= (see above) |
---|
1141 | // |
---|
1142 | // [37] NameTest ::= '*' | NCName ':' '*' | QName |
---|
1143 | // [5] NCName ::= (Letter | '_') (NCNameChar)* |
---|
1144 | // [?] NCNameChar ::= Letter | Digit | '.' | '-' | '_' (ascii subset of 'NCNameChar') |
---|
1145 | // [?] QName ::= (NCName ':')? NCName |
---|
1146 | // [?] Letter ::= [A-Za-z] (ascii subset of 'Letter') |
---|
1147 | // [?] Digit ::= [0-9] (ascii subset of 'Digit') |
---|
1148 | // |
---|
1149 | nameOffset = currentOffset; |
---|
1150 | currentOffset = scanNCName(data, endOffset, currentOffset); |
---|
1151 | if (currentOffset == nameOffset) { |
---|
1152 | return false; // REVISIT |
---|
1153 | } |
---|
1154 | |
---|
1155 | if (currentOffset < endOffset) { |
---|
1156 | ch = data[currentOffset]; |
---|
1157 | } |
---|
1158 | else { |
---|
1159 | ch = 0; |
---|
1160 | } |
---|
1161 | |
---|
1162 | dataBuffer.set(data + nameOffset, currentOffset - nameOffset); |
---|
1163 | nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); |
---|
1164 | |
---|
1165 | bool isNameTestNCName = false; |
---|
1166 | bool isAxisName = false; |
---|
1167 | prefixHandle = -1; |
---|
1168 | |
---|
1169 | if (ch == chColon) { |
---|
1170 | |
---|
1171 | if (++currentOffset == endOffset) { |
---|
1172 | return false; // REVISIT |
---|
1173 | } |
---|
1174 | |
---|
1175 | ch = data[currentOffset]; |
---|
1176 | |
---|
1177 | if (ch == chAsterisk) { |
---|
1178 | if (++currentOffset < endOffset) { |
---|
1179 | ch = data[currentOffset]; |
---|
1180 | } |
---|
1181 | |
---|
1182 | isNameTestNCName = true; |
---|
1183 | } else if (ch == chColon) { |
---|
1184 | if (++currentOffset < endOffset) { |
---|
1185 | ch = data[currentOffset]; |
---|
1186 | } |
---|
1187 | |
---|
1188 | isAxisName = true; |
---|
1189 | } else { |
---|
1190 | prefixHandle = nameHandle; |
---|
1191 | nameOffset = currentOffset; |
---|
1192 | currentOffset = scanNCName(data, endOffset, currentOffset); |
---|
1193 | if (currentOffset == nameOffset) { |
---|
1194 | return false; // REVISIT |
---|
1195 | } |
---|
1196 | if (currentOffset < endOffset) { |
---|
1197 | ch = data[currentOffset]; |
---|
1198 | } |
---|
1199 | else { |
---|
1200 | ch = 0; |
---|
1201 | } |
---|
1202 | |
---|
1203 | dataBuffer.set(data + nameOffset, currentOffset - nameOffset); |
---|
1204 | nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); |
---|
1205 | } |
---|
1206 | } |
---|
1207 | // |
---|
1208 | // [39] ExprWhitespace ::= S |
---|
1209 | // |
---|
1210 | while (XMLChar1_0::isWhitespace(ch)) { |
---|
1211 | if (++currentOffset == endOffset) { |
---|
1212 | break; |
---|
1213 | } |
---|
1214 | ch = data[currentOffset]; |
---|
1215 | } |
---|
1216 | |
---|
1217 | // |
---|
1218 | // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or |
---|
1219 | // an Operator, then an NCName must be recognized as an OperatorName. |
---|
1220 | // |
---|
1221 | if (starIsMultiplyOperator) { |
---|
1222 | if (nameHandle == fAndSymbol) { |
---|
1223 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_AND); |
---|
1224 | starIsMultiplyOperator = false; |
---|
1225 | } else if (nameHandle == fOrSymbol) { |
---|
1226 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_OR); |
---|
1227 | starIsMultiplyOperator = false; |
---|
1228 | } else if (nameHandle == fModSymbol) { |
---|
1229 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MOD); |
---|
1230 | starIsMultiplyOperator = false; |
---|
1231 | } else if (nameHandle == fDivSymbol) { |
---|
1232 | addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DIV); |
---|
1233 | starIsMultiplyOperator = false; |
---|
1234 | } else { |
---|
1235 | return false; // REVISIT |
---|
1236 | } |
---|
1237 | |
---|
1238 | if (isNameTestNCName) { |
---|
1239 | return false; // REVISIT - NCName:* where an OperatorName is required |
---|
1240 | } else if (isAxisName) { |
---|
1241 | return false; // REVISIT - AxisName:: where an OperatorName is required |
---|
1242 | } |
---|
1243 | break; |
---|
1244 | } |
---|
1245 | // |
---|
1246 | // If the character following an NCName (possibly after intervening ExprWhitespace) is (, |
---|
1247 | // then the token must be recognized as a NodeType or a FunctionName. |
---|
1248 | // |
---|
1249 | if (ch == chOpenParen && !isNameTestNCName && !isAxisName) { |
---|
1250 | if (nameHandle == fCommentSymbol) { |
---|
1251 | addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_COMMENT); |
---|
1252 | } else if (nameHandle == fTextSymbol) { |
---|
1253 | addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_TEXT); |
---|
1254 | } else if (nameHandle == fPISymbol) { |
---|
1255 | addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_PI); |
---|
1256 | } else if (nameHandle == fNodeSymbol) { |
---|
1257 | addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_NODE); |
---|
1258 | } else { |
---|
1259 | addToken(tokens, XercesXPath::EXPRTOKEN_FUNCTION_NAME); |
---|
1260 | tokens->addElement(prefixHandle); |
---|
1261 | tokens->addElement(nameHandle); |
---|
1262 | } |
---|
1263 | addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN); |
---|
1264 | starIsMultiplyOperator = false; |
---|
1265 | ++currentOffset; |
---|
1266 | break; |
---|
1267 | } |
---|
1268 | |
---|
1269 | // |
---|
1270 | // If the two characters following an NCName (possibly after intervening ExprWhitespace) |
---|
1271 | // are ::, then the token must be recognized as an AxisName. |
---|
1272 | // |
---|
1273 | if (isAxisName || |
---|
1274 | (ch == chColon && currentOffset + 1 < endOffset && |
---|
1275 | data[currentOffset + 1] == chColon)) { |
---|
1276 | |
---|
1277 | if (nameHandle == fAncestorSymbol) { |
---|
1278 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR); |
---|
1279 | } else if (nameHandle == fAncestorOrSelfSymbol) { |
---|
1280 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF); |
---|
1281 | } else if (nameHandle == fAttributeSymbol) { |
---|
1282 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE); |
---|
1283 | } else if (nameHandle == fChildSymbol) { |
---|
1284 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_CHILD); |
---|
1285 | } else if (nameHandle == fDescendantSymbol) { |
---|
1286 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT); |
---|
1287 | } else if (nameHandle == fDescendantOrSelfSymbol) { |
---|
1288 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF); |
---|
1289 | } else if (nameHandle == fFollowingSymbol) { |
---|
1290 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING); |
---|
1291 | } else if (nameHandle == fFollowingSiblingSymbol) { |
---|
1292 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING); |
---|
1293 | } else if (nameHandle == fNamespaceSymbol) { |
---|
1294 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_NAMESPACE); |
---|
1295 | } else if (nameHandle == fParentSymbol) { |
---|
1296 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PARENT); |
---|
1297 | } else if (nameHandle == fPrecedingSymbol) { |
---|
1298 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING); |
---|
1299 | } else if (nameHandle == fPrecedingSiblingSymbol) { |
---|
1300 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING_SIBLING); |
---|
1301 | } else if (nameHandle == fSelfSymbol) { |
---|
1302 | addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_SELF); |
---|
1303 | } else { |
---|
1304 | return false; // REVISIT |
---|
1305 | } |
---|
1306 | |
---|
1307 | if (isNameTestNCName) { |
---|
1308 | return false; // REVISIT - "NCName:* ::" where "AxisName ::" is required |
---|
1309 | } |
---|
1310 | |
---|
1311 | addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON); |
---|
1312 | starIsMultiplyOperator = false; |
---|
1313 | if (!isAxisName) { |
---|
1314 | currentOffset += 2; |
---|
1315 | } |
---|
1316 | break; |
---|
1317 | } |
---|
1318 | // |
---|
1319 | // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a |
---|
1320 | // FunctionName, or an AxisName. |
---|
1321 | // |
---|
1322 | if (isNameTestNCName) { |
---|
1323 | addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE); |
---|
1324 | tokens->addElement(nameHandle); |
---|
1325 | } else { |
---|
1326 | addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_QNAME); |
---|
1327 | tokens->addElement(prefixHandle); |
---|
1328 | tokens->addElement(nameHandle); |
---|
1329 | } |
---|
1330 | |
---|
1331 | starIsMultiplyOperator = true; |
---|
1332 | break; |
---|
1333 | } |
---|
1334 | default: |
---|
1335 | { |
---|
1336 | XMLCh str[2]= {ch, 0 }; |
---|
1337 | ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_InvalidChar, str, tokens->getMemoryManager()); |
---|
1338 | break; |
---|
1339 | } |
---|
1340 | } |
---|
1341 | } |
---|
1342 | |
---|
1343 | return true; |
---|
1344 | } |
---|
1345 | |
---|
1346 | |
---|
1347 | XMLSize_t XPathScanner::scanNCName(const XMLCh* const data, |
---|
1348 | const XMLSize_t endOffset, |
---|
1349 | XMLSize_t currentOffset) { |
---|
1350 | |
---|
1351 | XMLCh ch = data[currentOffset]; |
---|
1352 | |
---|
1353 | if (!XMLChar1_0::isFirstNCNameChar(ch)) { |
---|
1354 | return currentOffset; |
---|
1355 | } |
---|
1356 | |
---|
1357 | while (++currentOffset < endOffset) { |
---|
1358 | |
---|
1359 | ch = data[currentOffset]; |
---|
1360 | |
---|
1361 | if (!XMLChar1_0::isNCNameChar(ch)) { |
---|
1362 | break; |
---|
1363 | } |
---|
1364 | } |
---|
1365 | |
---|
1366 | return currentOffset; |
---|
1367 | } |
---|
1368 | |
---|
1369 | |
---|
1370 | XMLSize_t XPathScanner::scanNumber(const XMLCh* const data, |
---|
1371 | const XMLSize_t endOffset, |
---|
1372 | XMLSize_t currentOffset, |
---|
1373 | ValueVectorOf<int>* const tokens) { |
---|
1374 | |
---|
1375 | XMLCh ch = data[currentOffset]; |
---|
1376 | int whole = 0; |
---|
1377 | int part = 0; |
---|
1378 | |
---|
1379 | while (ch >= chDigit_0 && ch <= chDigit_9) { |
---|
1380 | |
---|
1381 | whole = (whole * 10) + (ch - chDigit_0); |
---|
1382 | |
---|
1383 | if (++currentOffset == endOffset) { |
---|
1384 | break; |
---|
1385 | } |
---|
1386 | |
---|
1387 | ch = data[currentOffset]; |
---|
1388 | } |
---|
1389 | |
---|
1390 | if (ch == chPeriod) { |
---|
1391 | |
---|
1392 | if (++currentOffset < endOffset) { |
---|
1393 | |
---|
1394 | ch = data[currentOffset]; |
---|
1395 | |
---|
1396 | while (ch >= chDigit_0 && ch <= chDigit_9) { |
---|
1397 | |
---|
1398 | part = (part * 10) + (ch - chDigit_0); |
---|
1399 | |
---|
1400 | if (++currentOffset == endOffset) { |
---|
1401 | break; |
---|
1402 | } |
---|
1403 | |
---|
1404 | ch = data[currentOffset]; |
---|
1405 | } |
---|
1406 | |
---|
1407 | if (part != 0) { |
---|
1408 | ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::XPath_FindSolution, tokens->getMemoryManager()); |
---|
1409 | } |
---|
1410 | } |
---|
1411 | } |
---|
1412 | |
---|
1413 | tokens->addElement(whole); |
---|
1414 | tokens->addElement(part); |
---|
1415 | |
---|
1416 | return currentOffset; |
---|
1417 | } |
---|
1418 | |
---|
1419 | |
---|
1420 | // --------------------------------------------------------------------------- |
---|
1421 | // XPathScannerForSchema: Constructors and Destructor |
---|
1422 | // --------------------------------------------------------------------------- |
---|
1423 | XPathScannerForSchema::XPathScannerForSchema(XMLStringPool* const stringPool) |
---|
1424 | : XPathScanner(stringPool) |
---|
1425 | { |
---|
1426 | } |
---|
1427 | |
---|
1428 | |
---|
1429 | // --------------------------------------------------------------------------- |
---|
1430 | // XPathScannerForSchema: Helper methods |
---|
1431 | // --------------------------------------------------------------------------- |
---|
1432 | void XPathScannerForSchema::addToken(ValueVectorOf<int>* const tokens, |
---|
1433 | const int aToken) { |
---|
1434 | |
---|
1435 | if (aToken == XercesXPath::EXPRTOKEN_ATSIGN || |
---|
1436 | aToken == XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE || |
---|
1437 | aToken == XercesXPath::EXPRTOKEN_AXISNAME_CHILD || |
---|
1438 | //token == XercesXPath::EXPRTOKEN_AXISNAME_SELF || |
---|
1439 | aToken == XercesXPath::EXPRTOKEN_DOUBLE_COLON || |
---|
1440 | aToken == XercesXPath::EXPRTOKEN_NAMETEST_QNAME || |
---|
1441 | //token == XercesXPath::EXPRTOKEN_NODETYPE_NODE || |
---|
1442 | aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH || |
---|
1443 | aToken == XercesXPath::EXPRTOKEN_PERIOD || |
---|
1444 | aToken == XercesXPath::EXPRTOKEN_NAMETEST_ANY || |
---|
1445 | aToken == XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE || |
---|
1446 | aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH || |
---|
1447 | aToken == XercesXPath::EXPRTOKEN_OPERATOR_UNION) { |
---|
1448 | |
---|
1449 | tokens->addElement(aToken); |
---|
1450 | return; |
---|
1451 | } |
---|
1452 | |
---|
1453 | ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_TokenNotSupported, tokens->getMemoryManager()); |
---|
1454 | } |
---|
1455 | |
---|
1456 | XERCES_CPP_NAMESPACE_END |
---|
1457 | |
---|
1458 | /** |
---|
1459 | * End of file XercesPath.cpp |
---|
1460 | */ |
---|