PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.8/extensions/src/ChannelArchiver/ThirdParty/xerces-c-src2_4_0/src/xercesc/internal/SGXMLScanner.cpp

http://atf2flightsim.googlecode.com/
C++ | 1841 lines | 1269 code | 209 blank | 363 comment | 288 complexity | c82c2af192c3febf07594ae13f12bdf5 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution,
  20. * if any, must include the following acknowledgment:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowledgment may appear in the software itself,
  24. * if and wherever such third-party acknowledgments normally appear.
  25. *
  26. * 4. The names "Xerces" and "Apache Software Foundation" must
  27. * not be used to endorse or promote products derived from this
  28. * software without prior written permission. For written
  29. * permission, please contact apache\@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache",
  32. * nor may "Apache" appear in their name, without prior written
  33. * permission of the Apache Software Foundation.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation, and was
  51. * originally based on software copyright (c) 1999, International
  52. * Business Machines, Inc., http://www.ibm.com . For more information
  53. * on the Apache Software Foundation, please see
  54. * <http://www.apache.org/>.
  55. */
  56. /*
  57. * $Id: SGXMLScanner.cpp,v 1.1.1.1 2009/03/14 06:42:19 whitegr Exp $
  58. */
  59. // ---------------------------------------------------------------------------
  60. // Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/internal/SGXMLScanner.hpp>
  63. #include <xercesc/util/RuntimeException.hpp>
  64. #include <xercesc/util/UnexpectedEOFException.hpp>
  65. #include <xercesc/framework/LocalFileInputSource.hpp>
  66. #include <xercesc/framework/URLInputSource.hpp>
  67. #include <xercesc/framework/XMLDocumentHandler.hpp>
  68. #include <xercesc/framework/XMLEntityHandler.hpp>
  69. #include <xercesc/framework/XMLPScanToken.hpp>
  70. #include <xercesc/framework/MemoryManager.hpp>
  71. #include <xercesc/framework/XMLGrammarPool.hpp>
  72. #include <xercesc/framework/XMLSchemaDescription.hpp>
  73. #include <xercesc/framework/psvi/PSVIHandler.hpp>
  74. #include <xercesc/framework/psvi/PSVIAttributeList.hpp>
  75. #include <xercesc/internal/EndOfEntityException.hpp>
  76. #include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
  77. #include <xercesc/validators/schema/SchemaValidator.hpp>
  78. #include <xercesc/validators/schema/TraverseSchema.hpp>
  79. #include <xercesc/validators/schema/XSDDOMParser.hpp>
  80. #include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
  81. #include <xercesc/validators/schema/identity/FieldActivator.hpp>
  82. #include <xercesc/validators/schema/identity/XPathMatcherStack.hpp>
  83. #include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
  84. #include <xercesc/validators/schema/identity/IC_Selector.hpp>
  85. #include <xercesc/validators/schema/identity/ValueStore.hpp>
  86. #include <xercesc/util/OutOfMemoryException.hpp>
  87. #include <xercesc/util/XMLResourceIdentifier.hpp>
  88. #include <xercesc/util/HashPtr.hpp>
  89. XERCES_CPP_NAMESPACE_BEGIN
  90. inline XMLAttDefList& getAttDefList(ComplexTypeInfo* currType, XMLElementDecl* elemDecl);
  91. // ---------------------------------------------------------------------------
  92. // SGXMLScanner: Constructors and Destructor
  93. // ---------------------------------------------------------------------------
  94. SGXMLScanner::SGXMLScanner( XMLValidator* const valToAdopt
  95. , GrammarResolver* const grammarResolver
  96. , MemoryManager* const manager) :
  97. XMLScanner(valToAdopt, grammarResolver, manager)
  98. , fSeeXsi(false)
  99. , fElemStateSize(16)
  100. , fElemState(0)
  101. , fContent(1023, manager)
  102. , fEntityTable(0)
  103. , fRawAttrList(0)
  104. , fSchemaValidator(0)
  105. , fMatcherStack(0)
  106. , fValueStoreCache(0)
  107. , fFieldActivator(0)
  108. , fElemNonDeclPool(0)
  109. , fElemCount(0)
  110. , fAttDefRegistry(0)
  111. , fUndeclaredAttrRegistryNS(0)
  112. , fPSVIAttrList(0)
  113. , fModel(0)
  114. , fPSVIElement(0)
  115. , fErrorStack(0)
  116. {
  117. try
  118. {
  119. commonInit();
  120. if (valToAdopt)
  121. {
  122. if (!valToAdopt->handlesSchema())
  123. ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  124. }
  125. else
  126. {
  127. fValidator = fSchemaValidator;
  128. }
  129. }
  130. catch(const OutOfMemoryException&)
  131. {
  132. throw;
  133. }
  134. catch(...)
  135. {
  136. cleanUp();
  137. throw;
  138. }
  139. }
  140. SGXMLScanner::SGXMLScanner( XMLDocumentHandler* const docHandler
  141. , DocTypeHandler* const docTypeHandler
  142. , XMLEntityHandler* const entityHandler
  143. , XMLErrorReporter* const errHandler
  144. , XMLValidator* const valToAdopt
  145. , GrammarResolver* const grammarResolver
  146. , MemoryManager* const manager) :
  147. XMLScanner(docHandler, docTypeHandler, entityHandler, errHandler, valToAdopt, grammarResolver, manager)
  148. , fSeeXsi(false)
  149. , fElemStateSize(16)
  150. , fElemState(0)
  151. , fContent(1023, manager)
  152. , fEntityTable(0)
  153. , fRawAttrList(0)
  154. , fSchemaValidator(0)
  155. , fMatcherStack(0)
  156. , fValueStoreCache(0)
  157. , fFieldActivator(0)
  158. , fElemNonDeclPool(0)
  159. , fElemCount(0)
  160. , fAttDefRegistry(0)
  161. , fUndeclaredAttrRegistryNS(0)
  162. , fPSVIAttrList(0)
  163. , fModel(0)
  164. , fPSVIElement(0)
  165. , fErrorStack(0)
  166. {
  167. try
  168. {
  169. commonInit();
  170. if (valToAdopt)
  171. {
  172. if (!valToAdopt->handlesSchema())
  173. ThrowXML(RuntimeException, XMLExcepts::Gen_NoSchemaValidator);
  174. }
  175. else
  176. {
  177. fValidator = fSchemaValidator;
  178. }
  179. }
  180. catch(const OutOfMemoryException&)
  181. {
  182. throw;
  183. }
  184. catch(...)
  185. {
  186. cleanUp();
  187. throw;
  188. }
  189. }
  190. SGXMLScanner::~SGXMLScanner()
  191. {
  192. cleanUp();
  193. }
  194. // ---------------------------------------------------------------------------
  195. // XMLScanner: Getter methods
  196. // ---------------------------------------------------------------------------
  197. NameIdPool<DTDEntityDecl>* SGXMLScanner::getEntityDeclPool()
  198. {
  199. return 0;
  200. }
  201. const NameIdPool<DTDEntityDecl>* SGXMLScanner::getEntityDeclPool() const
  202. {
  203. return 0;
  204. }
  205. // ---------------------------------------------------------------------------
  206. // SGXMLScanner: Main entry point to scan a document
  207. // ---------------------------------------------------------------------------
  208. void SGXMLScanner::scanDocument(const InputSource& src)
  209. {
  210. // Bump up the sequence id for this parser instance. This will invalidate
  211. // any previous progressive scan tokens.
  212. fSequenceId++;
  213. try
  214. {
  215. // Reset the scanner and its plugged in stuff for a new run. This
  216. // resets all the data structures, creates the initial reader and
  217. // pushes it on the stack, and sets up the base document path.
  218. scanReset(src);
  219. // If we have a document handler, then call the start document
  220. if (fDocHandler)
  221. fDocHandler->startDocument();
  222. // Scan the prolog part, which is everything before the root element
  223. // including the DTD subsets.
  224. scanProlog();
  225. // If we got to the end of input, then its not a valid XML file.
  226. // Else, go on to scan the content.
  227. if (fReaderMgr.atEOF())
  228. {
  229. emitError(XMLErrs::EmptyMainEntity);
  230. }
  231. else
  232. {
  233. // Scan content, and tell it its not an external entity
  234. if (scanContent(false))
  235. {
  236. // Do post-parse validation if required
  237. if (fValidate)
  238. {
  239. // We handle ID reference semantics at this level since
  240. // its required by XML 1.0.
  241. checkIDRefs();
  242. // Then allow the validator to do any extra stuff it wants
  243. // fValidator->postParseValidation();
  244. }
  245. // That went ok, so scan for any miscellaneous stuff
  246. if (!fReaderMgr.atEOF())
  247. scanMiscellaneous();
  248. }
  249. }
  250. // If we have a document handler, then call the end document
  251. if (fDocHandler)
  252. fDocHandler->endDocument();
  253. // Reset the reader manager to close all files, sockets, etc...
  254. fReaderMgr.reset();
  255. }
  256. // NOTE:
  257. //
  258. // In all of the error processing below, the emitError() call MUST come
  259. // before the flush of the reader mgr, or it will fail because it tries
  260. // to find out the position in the XML source of the error.
  261. catch(const XMLErrs::Codes)
  262. {
  263. // This is a 'first fatal error' type exit, so reset and fall through
  264. fReaderMgr.reset();
  265. }
  266. catch(const XMLValid::Codes)
  267. {
  268. // This is a 'first fatal error' type exit, so reset and fall through
  269. fReaderMgr.reset();
  270. }
  271. catch(const XMLException& excToCatch)
  272. {
  273. // Emit the error and catch any user exception thrown from here. Make
  274. // sure in all cases we flush the reader manager.
  275. fInException = true;
  276. try
  277. {
  278. if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  279. emitError
  280. (
  281. XMLErrs::XMLException_Warning
  282. , excToCatch.getType()
  283. , excToCatch.getMessage()
  284. );
  285. else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  286. emitError
  287. (
  288. XMLErrs::XMLException_Fatal
  289. , excToCatch.getType()
  290. , excToCatch.getMessage()
  291. );
  292. else
  293. emitError
  294. (
  295. XMLErrs::XMLException_Error
  296. , excToCatch.getType()
  297. , excToCatch.getMessage()
  298. );
  299. }
  300. catch(const OutOfMemoryException&)
  301. {
  302. throw;
  303. }
  304. catch(...)
  305. {
  306. // Flush the reader manager and rethrow user's error
  307. fReaderMgr.reset();
  308. throw;
  309. }
  310. // If it returned, then reset the reader manager and fall through
  311. fReaderMgr.reset();
  312. }
  313. catch(const OutOfMemoryException&)
  314. {
  315. throw;
  316. }
  317. catch(...)
  318. {
  319. // Reset and rethrow
  320. fReaderMgr.reset();
  321. throw;
  322. }
  323. }
  324. bool SGXMLScanner::scanNext(XMLPScanToken& token)
  325. {
  326. // Make sure this token is still legal
  327. if (!isLegalToken(token))
  328. ThrowXML(RuntimeException, XMLExcepts::Scan_BadPScanToken);
  329. // Find the next token and remember the reader id
  330. unsigned int orgReader;
  331. XMLTokens curToken;
  332. bool retVal = true;
  333. try
  334. {
  335. while (true)
  336. {
  337. // We have to handle any end of entity exceptions that happen here.
  338. // We could be at the end of X nested entities, each of which will
  339. // generate an end of entity exception as we try to move forward.
  340. try
  341. {
  342. curToken = senseNextToken(orgReader);
  343. break;
  344. }
  345. catch(const EndOfEntityException& toCatch)
  346. {
  347. // Send an end of entity reference event
  348. if (fDocHandler)
  349. fDocHandler->endEntityReference(toCatch.getEntity());
  350. }
  351. }
  352. if (curToken == Token_CharData)
  353. {
  354. scanCharData(fCDataBuf);
  355. }
  356. else if (curToken == Token_EOF)
  357. {
  358. if (!fElemStack.isEmpty())
  359. {
  360. const ElemStack::StackElem* topElem = fElemStack.popTop();
  361. emitError
  362. (
  363. XMLErrs::EndedWithTagsOnStack
  364. , topElem->fThisElement->getFullName()
  365. );
  366. }
  367. retVal = false;
  368. }
  369. else
  370. {
  371. // Its some sort of markup
  372. bool gotData = true;
  373. switch(curToken)
  374. {
  375. case Token_CData :
  376. // Make sure we are within content
  377. if (fElemStack.isEmpty())
  378. emitError(XMLErrs::CDATAOutsideOfContent);
  379. scanCDSection();
  380. break;
  381. case Token_Comment :
  382. scanComment();
  383. break;
  384. case Token_EndTag :
  385. scanEndTag(gotData);
  386. break;
  387. case Token_PI :
  388. scanPI();
  389. break;
  390. case Token_StartTag :
  391. scanStartTag(gotData);
  392. break;
  393. default :
  394. fReaderMgr.skipToChar(chOpenAngle);
  395. break;
  396. }
  397. if (orgReader != fReaderMgr.getCurrentReaderNum())
  398. emitError(XMLErrs::PartialMarkupInEntity);
  399. // If we hit the end, then do the miscellaneous part
  400. if (!gotData)
  401. {
  402. // Do post-parse validation if required
  403. if (fValidate)
  404. {
  405. // We handle ID reference semantics at this level since
  406. // its required by XML 1.0.
  407. checkIDRefs();
  408. // Then allow the validator to do any extra stuff it wants
  409. // fValidator->postParseValidation();
  410. }
  411. // That went ok, so scan for any miscellaneous stuff
  412. scanMiscellaneous();
  413. if (fValidate)
  414. fValueStoreCache->endDocument();
  415. if (fDocHandler)
  416. fDocHandler->endDocument();
  417. }
  418. }
  419. }
  420. // NOTE:
  421. //
  422. // In all of the error processing below, the emitError() call MUST come
  423. // before the flush of the reader mgr, or it will fail because it tries
  424. // to find out the position in the XML source of the error.
  425. catch(const XMLErrs::Codes)
  426. {
  427. // This is a 'first failure' exception, so reset and return failure
  428. fReaderMgr.reset();
  429. return false;
  430. }
  431. catch(const XMLValid::Codes)
  432. {
  433. // This is a 'first fatal error' type exit, so reset and reuturn failure
  434. fReaderMgr.reset();
  435. return false;
  436. }
  437. catch(const XMLException& excToCatch)
  438. {
  439. // Emit the error and catch any user exception thrown from here. Make
  440. // sure in all cases we flush the reader manager.
  441. fInException = true;
  442. try
  443. {
  444. if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)
  445. emitError
  446. (
  447. XMLErrs::XMLException_Warning
  448. , excToCatch.getType()
  449. , excToCatch.getMessage()
  450. );
  451. else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)
  452. emitError
  453. (
  454. XMLErrs::XMLException_Fatal
  455. , excToCatch.getType()
  456. , excToCatch.getMessage()
  457. );
  458. else
  459. emitError
  460. (
  461. XMLErrs::XMLException_Error
  462. , excToCatch.getType()
  463. , excToCatch.getMessage()
  464. );
  465. }
  466. catch(const OutOfMemoryException&)
  467. {
  468. throw;
  469. }
  470. catch(...)
  471. {
  472. // Reset and rethrow user error
  473. fReaderMgr.reset();
  474. throw;
  475. }
  476. // Reset and return failure
  477. fReaderMgr.reset();
  478. return false;
  479. }
  480. catch(const OutOfMemoryException&)
  481. {
  482. throw;
  483. }
  484. catch(...)
  485. {
  486. // Reset and rethrow original error
  487. fReaderMgr.reset();
  488. throw;
  489. }
  490. // If we hit the end, then flush the reader manager
  491. if (!retVal)
  492. fReaderMgr.reset();
  493. return retVal;
  494. }
  495. // ---------------------------------------------------------------------------
  496. // SGXMLScanner: Private scanning methods
  497. // ---------------------------------------------------------------------------
  498. // This method is called from scanStartTag() to handle the very raw initial
  499. // scan of the attributes. It just fills in the passed collection with
  500. // key/value pairs for each attribute. No processing is done on them at all.
  501. unsigned int
  502. SGXMLScanner::rawAttrScan(const XMLCh* const elemName
  503. , RefVectorOf<KVStringPair>& toFill
  504. , bool& isEmpty)
  505. {
  506. // Keep up with how many attributes we've seen so far, and how many
  507. // elements are available in the vector. This way we can reuse old
  508. // elements until we run out and then expand it.
  509. unsigned int attCount = 0;
  510. unsigned int curVecSize = toFill.size();
  511. // Assume it is not empty
  512. isEmpty = false;
  513. // We loop until we either see a /> or >, handling key/value pairs util
  514. // we get there. We place them in the passed vector, which we will expand
  515. // as required to hold them.
  516. while (true)
  517. {
  518. // Get the next character, which should be non-space
  519. XMLCh nextCh = fReaderMgr.peekNextChar();
  520. // If the next character is not a slash or closed angle bracket,
  521. // then it must be whitespace, since whitespace is required
  522. // between the end of the last attribute and the name of the next
  523. // one.
  524. //
  525. if (attCount)
  526. {
  527. if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))
  528. {
  529. if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))
  530. {
  531. // Ok, skip by them and get another char
  532. fReaderMgr.getNextChar();
  533. fReaderMgr.skipPastSpaces();
  534. nextCh = fReaderMgr.peekNextChar();
  535. }
  536. else
  537. {
  538. // Emit the error but keep on going
  539. emitError(XMLErrs::ExpectedWhitespace);
  540. }
  541. }
  542. }
  543. // Ok, here we first check for any of the special case characters.
  544. // If its not one, then we do the normal case processing, which
  545. // assumes that we've hit an attribute value, Otherwise, we do all
  546. // the special case checks.
  547. if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))
  548. {
  549. // Assume its going to be an attribute, so get a name from
  550. // the input.
  551. if (!fReaderMgr.getName(fAttNameBuf))
  552. {
  553. emitError(XMLErrs::ExpectedAttrName);
  554. fReaderMgr.skipPastChar(chCloseAngle);
  555. return attCount;
  556. }
  557. // And next must be an equal sign
  558. if (!scanEq())
  559. {
  560. static const XMLCh tmpList[] =
  561. {
  562. chSingleQuote, chDoubleQuote, chCloseAngle
  563. , chOpenAngle, chForwardSlash, chNull
  564. };
  565. emitError(XMLErrs::ExpectedEqSign);
  566. // Try to sync back up by skipping forward until we either
  567. // hit something meaningful.
  568. const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  569. if ((chFound == chCloseAngle) || (chFound == chForwardSlash))
  570. {
  571. // Jump back to top for normal processing of these
  572. continue;
  573. }
  574. else if ((chFound == chSingleQuote)
  575. || (chFound == chDoubleQuote)
  576. || fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  577. {
  578. // Just fall through assuming that the value is to follow
  579. }
  580. else if (chFound == chOpenAngle)
  581. {
  582. // Assume a malformed tag and that new one is starting
  583. emitError(XMLErrs::UnterminatedStartTag, elemName);
  584. return attCount;
  585. }
  586. else
  587. {
  588. // Something went really wrong
  589. return attCount;
  590. }
  591. }
  592. // Next should be the quoted attribute value. We just do a simple
  593. // and stupid scan of this value. The only thing we do here
  594. // is to expand entity references.
  595. if (!basicAttrValueScan(fAttNameBuf.getRawBuffer(), fAttValueBuf))
  596. {
  597. static const XMLCh tmpList[] =
  598. {
  599. chCloseAngle, chOpenAngle, chForwardSlash, chNull
  600. };
  601. emitError(XMLErrs::ExpectedAttrValue);
  602. // It failed, so lets try to get synced back up. We skip
  603. // forward until we find some whitespace or one of the
  604. // chars in our list.
  605. const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);
  606. if ((chFound == chCloseAngle)
  607. || (chFound == chForwardSlash)
  608. || fReaderMgr.getCurrentReader()->isWhitespace(chFound))
  609. {
  610. // Just fall through and process this attribute, though
  611. // the value will be "".
  612. }
  613. else if (chFound == chOpenAngle)
  614. {
  615. // Assume a malformed tag and that new one is starting
  616. emitError(XMLErrs::UnterminatedStartTag, elemName);
  617. return attCount;
  618. }
  619. else
  620. {
  621. // Something went really wrong
  622. return attCount;
  623. }
  624. }
  625. // Make sure that the name is basically well formed for namespace
  626. // enabled rules. It either has no colons, or it has one which
  627. // is neither the first or last char.
  628. const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);
  629. if (colonFirst != -1)
  630. {
  631. const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);
  632. if (colonFirst != colonLast)
  633. {
  634. emitError(XMLErrs::TooManyColonsInName);
  635. continue;
  636. }
  637. else if ((colonFirst == 0)
  638. || (colonLast == (int)fAttNameBuf.getLen() - 1))
  639. {
  640. emitError(XMLErrs::InvalidColonPos);
  641. continue;
  642. }
  643. }
  644. // And now lets add it to the passed collection. If we have not
  645. // filled it up yet, then we use the next element. Else we add
  646. // a new one.
  647. KVStringPair* curPair = 0;
  648. if (attCount >= curVecSize)
  649. {
  650. curPair = new (fMemoryManager) KVStringPair
  651. (
  652. fAttNameBuf.getRawBuffer()
  653. , fAttValueBuf.getRawBuffer()
  654. , fMemoryManager
  655. );
  656. toFill.addElement(curPair);
  657. }
  658. else
  659. {
  660. curPair = toFill.elementAt(attCount);
  661. curPair->set(fAttNameBuf.getRawBuffer(), fAttValueBuf.getRawBuffer());
  662. }
  663. // And bump the count of attributes we've gotten
  664. attCount++;
  665. // And go to the top again for another attribute
  666. continue;
  667. }
  668. // It was some special case character so do all of the checks and
  669. // deal with it.
  670. if (!nextCh)
  671. ThrowXML(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF);
  672. if (nextCh == chForwardSlash)
  673. {
  674. fReaderMgr.getNextChar();
  675. isEmpty = true;
  676. if (!fReaderMgr.skippedChar(chCloseAngle))
  677. emitError(XMLErrs::UnterminatedStartTag, elemName);
  678. break;
  679. }
  680. else if (nextCh == chCloseAngle)
  681. {
  682. fReaderMgr.getNextChar();
  683. break;
  684. }
  685. else if (nextCh == chOpenAngle)
  686. {
  687. // Check for this one specially, since its going to be common
  688. // and it is kind of auto-recovering since we've already hit the
  689. // next open bracket, which is what we would have seeked to (and
  690. // skipped this whole tag.)
  691. emitError(XMLErrs::UnterminatedStartTag, elemName);
  692. break;
  693. }
  694. else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))
  695. {
  696. // Check for this one specially, which is probably a missing
  697. // attribute name, e.g. ="value". Just issue expected name
  698. // error and eat the quoted string, then jump back to the
  699. // top again.
  700. emitError(XMLErrs::ExpectedAttrName);
  701. fReaderMgr.getNextChar();
  702. fReaderMgr.skipQuotedString(nextCh);
  703. fReaderMgr.skipPastSpaces();
  704. continue;
  705. }
  706. }
  707. return attCount;
  708. }
  709. // This method will kick off the scanning of the primary content of the
  710. // document, i.e. the elements.
  711. bool SGXMLScanner::scanContent(const bool extEntity)
  712. {
  713. // Go into a loop until we hit the end of the root element, or we fall
  714. // out because there is no root element.
  715. //
  716. // We have to do kind of a deeply nested double loop here in order to
  717. // avoid doing the setup/teardown of the exception handler on each
  718. // round. Doing it this way we only do it when an exception actually
  719. // occurs.
  720. bool gotData = true;
  721. bool inMarkup = false;
  722. while (gotData)
  723. {
  724. try
  725. {
  726. while (gotData)
  727. {
  728. // Sense what the next top level token is. According to what
  729. // this tells us, we will call something to handle that kind
  730. // of thing.
  731. unsigned int orgReader;
  732. const XMLTokens curToken = senseNextToken(orgReader);
  733. // Handle character data and end of file specially. Char data
  734. // is not markup so we don't want to handle it in the loop
  735. // below.
  736. if (curToken == Token_CharData)
  737. {
  738. // Scan the character data and call appropriate events. Let
  739. // him use our local character data buffer for efficiency.
  740. scanCharData(fCDataBuf);
  741. continue;
  742. }
  743. else if (curToken == Token_EOF)
  744. {
  745. // The element stack better be empty at this point or we
  746. // ended prematurely before all elements were closed.
  747. if (!fElemStack.isEmpty())
  748. {
  749. const ElemStack::StackElem* topElem = fElemStack.popTop();
  750. emitError
  751. (
  752. XMLErrs::EndedWithTagsOnStack
  753. , topElem->fThisElement->getFullName()
  754. );
  755. }
  756. // Its the end of file, so clear the got data flag
  757. gotData = false;
  758. continue;
  759. }
  760. // We are in some sort of markup now
  761. inMarkup = true;
  762. // According to the token we got, call the appropriate
  763. // scanning method.
  764. switch(curToken)
  765. {
  766. case Token_CData :
  767. // Make sure we are within content
  768. if (fElemStack.isEmpty())
  769. emitError(XMLErrs::CDATAOutsideOfContent);
  770. scanCDSection();
  771. break;
  772. case Token_Comment :
  773. scanComment();
  774. break;
  775. case Token_EndTag :
  776. scanEndTag(gotData);
  777. break;
  778. case Token_PI :
  779. scanPI();
  780. break;
  781. case Token_StartTag :
  782. scanStartTag(gotData);
  783. break;
  784. default :
  785. fReaderMgr.skipToChar(chOpenAngle);
  786. break;
  787. }
  788. if (orgReader != fReaderMgr.getCurrentReaderNum())
  789. emitError(XMLErrs::PartialMarkupInEntity);
  790. // And we are back out of markup again
  791. inMarkup = false;
  792. }
  793. }
  794. catch(const EndOfEntityException& toCatch)
  795. {
  796. // If we were in some markup when this happened, then its a
  797. // partial markup error.
  798. if (inMarkup)
  799. emitError(XMLErrs::PartialMarkupInEntity);
  800. // Send an end of entity reference event
  801. if (fDocHandler)
  802. fDocHandler->endEntityReference(toCatch.getEntity());
  803. inMarkup = false;
  804. }
  805. }
  806. // It went ok, so return success
  807. return true;
  808. }
  809. void SGXMLScanner::scanEndTag(bool& gotData)
  810. {
  811. // Assume we will still have data until proven otherwise. It will only
  812. // ever be false if this is the end of the root element.
  813. gotData = true;
  814. // Check if the element stack is empty. If so, then this is an unbalanced
  815. // element (i.e. more ends than starts, perhaps because of bad text
  816. // causing one to be skipped.)
  817. if (fElemStack.isEmpty())
  818. {
  819. emitError(XMLErrs::MoreEndThanStartTags);
  820. fReaderMgr.skipPastChar(chCloseAngle);
  821. ThrowXML(RuntimeException, XMLExcepts::Scan_UnbalancedStartEnd);
  822. }
  823. // After the </ is the element QName, so get a name from the input
  824. if (!fReaderMgr.getName(fQNameBuf))
  825. {
  826. // It failed so we can't really do anything with it
  827. emitError(XMLErrs::ExpectedElementName);
  828. fReaderMgr.skipPastChar(chCloseAngle);
  829. return;
  830. }
  831. int prefixColonPos = -1;
  832. unsigned int uriId = resolveQName
  833. (
  834. fQNameBuf.getRawBuffer()
  835. , fPrefixBuf
  836. , ElemStack::Mode_Element
  837. , prefixColonPos
  838. );
  839. // Pop the stack of the element we are supposed to be ending. Remember
  840. // that we don't own this. The stack just keeps them and reuses them.
  841. //
  842. // NOTE: We CANNOT do this until we've resolved the element name because
  843. // the element stack top contains the prefix to URI mappings for this
  844. // element.
  845. unsigned int topUri = fElemStack.getCurrentURI();
  846. const ElemStack::StackElem* topElem = fElemStack.popTop();
  847. // See if it was the root element, to avoid multiple calls below
  848. const bool isRoot = fElemStack.isEmpty();
  849. // Make sure that its the end of the element that we expect
  850. XMLElementDecl* tempElement = topElem->fThisElement;
  851. const XMLCh* rawNameBuf = fQNameBuf.getRawBuffer();
  852. if ((topUri != uriId) ||
  853. (!XMLString::equals(tempElement->getBaseName(), &rawNameBuf[prefixColonPos + 1])))
  854. {
  855. emitError
  856. (
  857. XMLErrs::ExpectedEndOfTagX
  858. , topElem->fThisElement->getFullName()
  859. );
  860. }
  861. // Make sure we are back on the same reader as where we started
  862. if (topElem->fReaderNum != fReaderMgr.getCurrentReaderNum())
  863. emitError(XMLErrs::PartialTagMarkupError);
  864. // Skip optional whitespace
  865. fReaderMgr.skipPastSpaces();
  866. // Make sure we find the closing bracket
  867. if (!fReaderMgr.skippedChar(chCloseAngle))
  868. {
  869. emitError
  870. (
  871. XMLErrs::UnterminatedEndTag
  872. , topElem->fThisElement->getFullName()
  873. );
  874. }
  875. if (fPSVIHandler)
  876. {
  877. if (fValidate && topElem->fThisElement->isDeclared())
  878. {
  879. fPSVIElemContext.fCurrentDV = ((SchemaValidator*) fValidator)->getCurrentDatatypeValidator();
  880. fPSVIElemContext.fCurrentTypeInfo = ((SchemaValidator*) fValidator)->getCurrentTypeInfo();
  881. fPSVIElemContext.fNormalizedValue = ((SchemaValidator*) fValidator)->getNormalizedValue();
  882. if (XMLString::equals(fPSVIElemContext.fNormalizedValue, XMLUni::fgZeroLenString))
  883. fPSVIElemContext.fNormalizedValue = 0;
  884. }
  885. else
  886. {
  887. fPSVIElemContext.fCurrentDV = 0;
  888. fPSVIElemContext.fCurrentTypeInfo = 0;
  889. fPSVIElemContext.fNormalizedValue = 0;
  890. }
  891. }
  892. // If validation is enabled, then lets pass him the list of children and
  893. // this element and let him validate it.
  894. DatatypeValidator* psviMemberType = 0;
  895. if (fValidate)
  896. {
  897. int res = fValidator->checkContent
  898. (
  899. topElem->fThisElement
  900. , topElem->fChildren
  901. , topElem->fChildCount
  902. );
  903. if (res >= 0)
  904. {
  905. // One of the elements is not valid for the content. NOTE that
  906. // if no children were provided but the content model requires
  907. // them, it comes back with a zero value. But we cannot use that
  908. // to index the child array in this case, and have to put out a
  909. // special message.
  910. if (!topElem->fChildCount)
  911. {
  912. fValidator->emitError
  913. (
  914. XMLValid::EmptyNotValidForContent
  915. , topElem->fThisElement->getFormattedContentModel()
  916. );
  917. }
  918. else if ((unsigned int)res >= topElem->fChildCount)
  919. {
  920. fValidator->emitError
  921. (
  922. XMLValid::NotEnoughElemsForCM
  923. , topElem->fThisElement->getFormattedContentModel()
  924. );
  925. }
  926. else
  927. {
  928. fValidator->emitError
  929. (
  930. XMLValid::ElementNotValidForContent
  931. , topElem->fChildren[res]->getRawName()
  932. , topElem->fThisElement->getFormattedContentModel()
  933. );
  934. }
  935. }
  936. // update PSVI info
  937. if (fPSVIHandler)
  938. {
  939. fPSVIElemContext.fIsSpecified = ((SchemaValidator*) fValidator)->getIsElemSpecified();
  940. if (((SchemaValidator*) fValidator)->getErrorOccurred())
  941. fPSVIElemContext.fErrorOccurred = true;
  942. else if (fPSVIElemContext.fCurrentDV->getType() == DatatypeValidator::Union)
  943. psviMemberType = fValidationContext->getValidatingMemberType();
  944. }
  945. // call matchers and de-activate context
  946. int oldCount = fMatcherStack->getMatcherCount();
  947. if (oldCount ||
  948. ((SchemaElementDecl*)topElem->fThisElement)->getIdentityConstraintCount()) {
  949. for (int i = oldCount - 1; i >= 0; i--) {
  950. XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
  951. matcher->endElement(*(topElem->fThisElement), fContent.getRawBuffer());
  952. }
  953. if (fMatcherStack->size() > 0) {
  954. fMatcherStack->popContext();
  955. }
  956. // handle everything *but* keyref's.
  957. int newCount = fMatcherStack->getMatcherCount();
  958. for (int j = oldCount - 1; j >= newCount; j--) {
  959. XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
  960. IdentityConstraint* ic = matcher->getIdentityConstraint();
  961. if (ic && (ic->getType() != IdentityConstraint::KEYREF))
  962. fValueStoreCache->transplant(ic, matcher->getInitialDepth());
  963. }
  964. // now handle keyref's...
  965. for (int k = oldCount - 1; k >= newCount; k--) {
  966. XPathMatcher* matcher = fMatcherStack->getMatcherAt(k);
  967. IdentityConstraint* ic = matcher->getIdentityConstraint();
  968. if (ic && (ic->getType() == IdentityConstraint::KEYREF)) {
  969. ValueStore* values = fValueStoreCache->getValueStoreFor(ic, matcher->getInitialDepth());
  970. if (values) { // nothing to do if nothing matched!
  971. values->endDcocumentFragment(fValueStoreCache);
  972. }
  973. }
  974. }
  975. fValueStoreCache->endElement();
  976. }
  977. }
  978. if(!isRoot)
  979. ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(topElem->fThisElement, fGrammarType);
  980. if (fPSVIHandler)
  981. {
  982. endElementPSVI
  983. (
  984. (SchemaElementDecl*)topElem->fThisElement, psviMemberType
  985. );
  986. }
  987. // If we have a doc handler, tell it about the end tag
  988. if (fDocHandler)
  989. {
  990. fDocHandler->endElement
  991. (
  992. *topElem->fThisElement
  993. , uriId
  994. , isRoot
  995. , fPrefixBuf.getRawBuffer()
  996. );
  997. }
  998. // reset xsi:type ComplexTypeInfo
  999. ((SchemaElementDecl*)topElem->fThisElement)->reset();
  1000. if (!isRoot)
  1001. ((SchemaElementDecl*)(fElemStack.topElement()->fThisElement))->
  1002. setXsiComplexTypeInfo(((SchemaValidator*)fValidator)->getCurrentTypeInfo());
  1003. // If this was the root, then done with content
  1004. gotData = !isRoot;
  1005. if (gotData) {
  1006. // Restore the grammar
  1007. fGrammar = fElemStack.getCurrentGrammar();
  1008. fGrammarType = fGrammar->getGrammarType();
  1009. fValidator->setGrammar(fGrammar);
  1010. // Restore the validation flag
  1011. fValidate = fElemStack.getValidationFlag();
  1012. }
  1013. }
  1014. // This method handles the high level logic of scanning the DOCType
  1015. // declaration. This calls the DTDScanner and kicks off both the scanning of
  1016. // the internal subset and the scanning of the external subset, if any.
  1017. //
  1018. // When we get here the '<!DOCTYPE' part has already been scanned, which is
  1019. // what told us that we had a doc type decl to parse.
  1020. void SGXMLScanner::scanDocTypeDecl()
  1021. {
  1022. // Just skips over it
  1023. // REVISIT: Should we issue a warning
  1024. static const XMLCh doctypeIE[] =
  1025. {
  1026. chOpenSquare, chCloseAngle, chNull
  1027. };
  1028. XMLCh nextCh = fReaderMgr.skipUntilIn(doctypeIE);
  1029. if (nextCh == chOpenSquare)
  1030. fReaderMgr.skipPastChar(chCloseSquare);
  1031. fReaderMgr.skipPastChar(chCloseAngle);
  1032. }
  1033. // This method is called to scan a start tag when we are processing
  1034. // namespaces. This method is called after we've scanned the < of a
  1035. // start tag. So we have to get the element name, then scan the attributes,
  1036. // after which we are either going to see >, />, or attributes followed
  1037. // by one of those sequences.
  1038. bool SGXMLScanner::scanStartTag(bool& gotData)
  1039. {
  1040. // Assume we will still have data until proven otherwise. It will only
  1041. // ever be false if this is the root and its empty.
  1042. gotData = true;
  1043. // Reset element content
  1044. fContent.reset();
  1045. // The current position is after the open bracket, so we need to read in
  1046. // in the element name.
  1047. if (!fReaderMgr.getName(fQNameBuf))
  1048. {
  1049. emitError(XMLErrs::ExpectedElementName);
  1050. fReaderMgr.skipToChar(chOpenAngle);
  1051. return false;
  1052. }
  1053. // See if its the root element
  1054. const bool isRoot = fElemStack.isEmpty();
  1055. // Skip any whitespace after the name
  1056. fReaderMgr.skipPastSpaces();
  1057. // First we have to do the rawest attribute scan. We don't do any
  1058. // normalization of them at all, since we don't know yet what type they
  1059. // might be (since we need the element decl in order to do that.)
  1060. bool isEmpty;
  1061. unsigned int attCount = rawAttrScan
  1062. (
  1063. fQNameBuf.getRawBuffer()
  1064. , *fRawAttrList
  1065. , isEmpty
  1066. );
  1067. const bool gotAttrs = (attCount != 0);
  1068. // save the contentleafname and currentscope before addlevel, for later use
  1069. ContentLeafNameTypeVector* cv = 0;
  1070. XMLContentModel* cm = 0;
  1071. int currentScope = Grammar::TOP_LEVEL_SCOPE;
  1072. bool laxThisOne = false;
  1073. if (!isRoot)
  1074. {
  1075. // schema validator will have correct type if validating
  1076. SchemaElementDecl* tempElement = (SchemaElementDecl*)
  1077. fElemStack.topElement()->fThisElement;
  1078. SchemaElementDecl::ModelTypes modelType = tempElement->getModelType();
  1079. ComplexTypeInfo *currType = 0;
  1080. if (fValidate)
  1081. {
  1082. currType = ((SchemaValidator*)fValidator)->getCurrentTypeInfo();
  1083. if (currType)
  1084. modelType = (SchemaElementDecl::ModelTypes)currType->getContentType();
  1085. else // something must have gone wrong
  1086. modelType = SchemaElementDecl::Any;
  1087. }
  1088. else
  1089. {
  1090. currType = tempElement->getComplexTypeInfo();
  1091. }
  1092. if ((modelType == SchemaElementDecl::Mixed_Simple)
  1093. || (modelType == SchemaElementDecl::Mixed_Complex)
  1094. || (modelType == SchemaElementDecl::Children))
  1095. {
  1096. cm = currType->getContentModel();
  1097. cv = cm->getContentLeafNameTypeVector();
  1098. currentScope = fElemStack.getCurrentScope();
  1099. }
  1100. else if (modelType == SchemaElementDecl::Any) {
  1101. laxThisOne = true;
  1102. }
  1103. }
  1104. // Now, since we might have to update the namespace map for this element,
  1105. // but we don't have the element decl yet, we just tell the element stack
  1106. // to expand up to get ready.
  1107. unsigned int elemDepth = fElemStack.addLevel();
  1108. fElemStack.setValidationFlag(fValidate);
  1109. // Check if there is any external schema location specified, and if we are at root,
  1110. // go through them first before scanning those specified in the instance document
  1111. if (isRoot
  1112. && (fExternalSchemaLocation || fExternalNoNamespaceSchemaLocation)) {
  1113. if (fExternalSchemaLocation)
  1114. parseSchemaLocation(fExternalSchemaLocation);
  1115. if (fExternalNoNamespaceSchemaLocation)
  1116. resolveSchemaGrammar(fExternalNoNamespaceSchemaLocation, XMLUni::fgZeroLenString);
  1117. }
  1118. // Make an initial pass through the list and find any xmlns attributes or
  1119. // schema attributes.
  1120. if (attCount)
  1121. scanRawAttrListforNameSpaces(fRawAttrList, attCount);
  1122. // Resolve the qualified name to a URI and name so that we can look up
  1123. // the element decl for this element. We have now update the prefix to
  1124. // namespace map so we should get the correct element now.
  1125. int prefixColonPos = -1;
  1126. const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
  1127. unsigned int uriId = resolveQName
  1128. (
  1129. qnameRawBuf
  1130. , fPrefixBuf
  1131. , ElemStack::Mode_Element
  1132. , prefixColonPos
  1133. );
  1134. //if schema, check if we should lax or skip the validation of this element
  1135. bool parentValidation = fValidate;
  1136. if (cv) {
  1137. QName element(fPrefixBuf.getRawBuffer(), &qnameRawBuf[prefixColonPos + 1], uriId, fMemoryManager);
  1138. // elementDepth will be > 0, as cv is only constructed if element is not
  1139. // root.
  1140. laxThisOne = laxElementValidation(&element, cv, cm, elemDepth - 1);
  1141. }
  1142. // Look up the element now in the grammar. This will get us back a
  1143. // generic element decl object. We tell him to fault one in if he does
  1144. // not find it.
  1145. XMLElementDecl* elemDecl = 0;
  1146. bool wasAdded = false;
  1147. bool errorBeforeElementFound = false;
  1148. bool laxBeforeElementFound = false;
  1149. const XMLCh* nameRawBuf = &qnameRawBuf[prefixColonPos + 1];
  1150. const XMLCh* original_uriStr = fGrammar->getTargetNamespace();
  1151. unsigned orgGrammarUri = fURIStringPool->getId(original_uriStr);
  1152. if (uriId != fEmptyNamespaceId) {
  1153. // Check in current grammar before switching if necessary
  1154. elemDecl = fGrammar->getElemDecl
  1155. (
  1156. uriId
  1157. , nameRawBuf
  1158. , qnameRawBuf
  1159. , currentScope
  1160. );
  1161. if(!elemDecl)
  1162. {
  1163. // look in the list of undeclared elements, as would have been done
  1164. // before we made grammars stateless:
  1165. elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId, currentScope);
  1166. }
  1167. if (!elemDecl && (orgGrammarUri != uriId)) {
  1168. // not found, switch to the specified grammar
  1169. const XMLCh* uriStr = getURIText(uriId);
  1170. bool errorCondition = !switchGrammar(uriStr) && fValidate;
  1171. if (errorCondition && !laxThisOne)
  1172. {
  1173. fValidator->emitError
  1174. (
  1175. XMLValid::GrammarNotFound
  1176. ,uriStr
  1177. );
  1178. errorBeforeElementFound = true;
  1179. }
  1180. else if(errorCondition)
  1181. laxBeforeElementFound = true;
  1182. elemDecl = fGrammar->getElemDecl
  1183. (
  1184. uriId
  1185. , nameRawBuf
  1186. , qnameRawBuf
  1187. , currentScope
  1188. );
  1189. }
  1190. if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE) {
  1191. // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
  1192. elemDecl = fGrammar->getElemDecl
  1193. (
  1194. uriId
  1195. , nameRawBuf
  1196. , qnameRawBuf
  1197. , Grammar::TOP_LEVEL_SCOPE
  1198. );
  1199. if(!elemDecl)
  1200. {
  1201. // look in the list of undeclared elements, as would have been done
  1202. // before we made grammars stateless:
  1203. elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId, Grammar::TOP_LEVEL_SCOPE);
  1204. }
  1205. if(!elemDecl) {
  1206. // still not found in specified uri
  1207. // try emptyNamesapce see if element should be un-qualified.
  1208. elemDecl = fGrammar->getElemDecl
  1209. (
  1210. fEmptyNamespaceId
  1211. , nameRawBuf
  1212. , qnameRawBuf
  1213. , currentScope
  1214. );
  1215. bool errorCondition = elemDecl && elemDecl->getCreateReason() != XMLElementDecl::JustFaultIn;
  1216. if (errorCondition && fValidate) {
  1217. fValidator->emitError
  1218. (
  1219. XMLValid::ElementNotUnQualified
  1220. , elemDecl->getFullName()
  1221. );
  1222. errorBeforeElementFound = true;
  1223. }
  1224. else if(errorCondition)
  1225. laxBeforeElementFound = true;
  1226. }
  1227. }
  1228. if (!elemDecl) {
  1229. // still not found, fault this in and issue error later
  1230. // switch back to original grammar first
  1231. switchGrammar(original_uriStr);
  1232. elemDecl = new (fMemoryManager) SchemaElementDecl
  1233. (
  1234. fPrefixBuf.getRawBuffer()
  1235. , nameRawBuf
  1236. , uriId
  1237. , SchemaElementDecl::Any
  1238. , Grammar::TOP_LEVEL_SCOPE
  1239. , fMemoryManager
  1240. );
  1241. elemDecl->setId(fElemNonDeclPool->put((void*)elemDecl->getBaseName(), uriId, currentScope, (SchemaElementDecl*)elemDecl));
  1242. wasAdded = true;
  1243. }
  1244. }
  1245. else if (!elemDecl)
  1246. {
  1247. //the element has no prefix,
  1248. //thus it is either a non-qualified element defined in current targetNS
  1249. //or an element that is defined in the globalNS
  1250. //try unqualifed first
  1251. elemDecl = fGrammar->getElemDecl
  1252. (
  1253. uriId
  1254. , nameRawBuf
  1255. , qnameRawBuf
  1256. , currentScope
  1257. );
  1258. if(!elemDecl)
  1259. {
  1260. // look in the list of undeclared elements, as would have been done
  1261. // before we made grammars stateless:
  1262. elemDecl = fElemNonDeclPool->getByKey(nameRawBuf, uriId, currentScope);
  1263. }
  1264. if (!elemDecl && orgGrammarUri != fEmptyNamespaceId) {
  1265. //not found, switch grammar and try globalNS
  1266. bool errorCondition = !switchGrammar(XMLUni::fgZeroLenString) && fValidate;
  1267. if (errorCondition && !laxThisOne)
  1268. {
  1269. fValidator->emitError
  1270. (
  1271. XMLValid::GrammarNotFound
  1272. , XMLUni::fgZ

Large files files are truncated, but you can click here to view the full file