source: icXML/icXML-devel/src/icxercesc/parsers/AbstractDOMParser.cpp @ 2732

Last change on this file since 2732 was 2732, checked in by cameron, 6 years ago

icXML version of SchemaSymbols?

File size: 53.0 KB
Line 
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*  This file contains code to build the DOM tree. It registers a document
20*  handler with the scanner. In these handler methods, appropriate DOM nodes
21*  are created and added to the DOM tree.
22*
23* $Id: AbstractDOMParser.cpp 935358 2010-04-18 15:40:35Z borisk $
24*
25*/
26
27// ---------------------------------------------------------------------------
28//  Includes
29// ---------------------------------------------------------------------------
30#include <icxercesc/parsers/AbstractDOMParser.hpp>
31#include <xercesc/internal/XMLScannerResolver.hpp>
32#include <icxercesc/internal/ElemStack.hpp>
33#include <xercesc/util/XMLUniDefs.hpp>
34#include <xercesc/framework/XMLNotationDecl.hpp>
35#include <icxercesc/framework/XMLValidator.hpp>
36#include <xercesc/framework/psvi/PSVIElement.hpp>
37#include <xercesc/framework/psvi/PSVIAttribute.hpp>
38#include <xercesc/framework/psvi/PSVIAttributeList.hpp>
39#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
40#include <xercesc/util/IOException.hpp>
41#include <xercesc/dom/DOMImplementation.hpp>
42#include <xercesc/dom/DOMImplementationRegistry.hpp>
43#include <xercesc/dom/DOMElement.hpp>
44#include <xercesc/dom/impl/DOMAttrImpl.hpp>
45#include <xercesc/dom/impl/DOMAttrNSImpl.hpp>
46#include <xercesc/dom/impl/DOMTypeInfoImpl.hpp>
47#include <xercesc/dom/impl/DOMCDATASectionImpl.hpp>
48#include <xercesc/dom/DOMComment.hpp>
49#include <xercesc/dom/impl/DOMTextImpl.hpp>
50#include <xercesc/dom/impl/DOMDocumentImpl.hpp>
51#include <xercesc/dom/impl/DOMDocumentTypeImpl.hpp>
52#include <xercesc/dom/DOMDocumentType.hpp>
53#include <xercesc/dom/impl/DOMElementNSImpl.hpp>
54#include <xercesc/dom/impl/DOMEntityImpl.hpp>
55#include <xercesc/dom/impl/DOMEntityReferenceImpl.hpp>
56#include <xercesc/dom/impl/DOMNotationImpl.hpp>
57#include <xercesc/dom/DOMNamedNodeMap.hpp>
58#include <xercesc/dom/DOMProcessingInstruction.hpp>
59#include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp>
60#include <xercesc/dom/impl/DOMNodeIDMap.hpp>
61#include <xercesc/dom/impl/DOMCasts.hpp>
62#include <xercesc/validators/common/ContentSpecNode.hpp>
63#include <icxercesc/validators/common/GrammarResolver.hpp>
64#include <icxercesc/validators/schema/SchemaSymbols.hpp>
65#include <xercesc/util/OutOfMemoryException.hpp>
66#include <xercesc/xinclude/XIncludeUtils.hpp>
67
68XERCES_CPP_NAMESPACE_BEGIN
69
70
71// ---------------------------------------------------------------------------
72//  AbstractDOMParser: Constructors and Destructor
73// ---------------------------------------------------------------------------
74
75
76typedef JanitorMemFunCall<AbstractDOMParser>    CleanupType;
77typedef JanitorMemFunCall<AbstractDOMParser>    ResetInProgressType;
78
79
80AbstractDOMParser::AbstractDOMParser( XMLValidator* const   valToAdopt
81                                                                        , MemoryManager* const  manager
82                                                                        , XMLGrammarPool* const gramPool) :
83
84  fCreateEntityReferenceNodes(true)
85, fIncludeIgnorableWhitespace(true)
86, fWithinElement(false)
87, fParseInProgress(false)
88, fCreateCommentNodes(true)
89, fDocumentAdoptedByUser(false)
90, fCreateSchemaInfo(false)
91, fDoXInclude(false)
92, fScanner(0)
93, fImplementationFeatures(0)
94, fCurrentParent(0)
95, fCurrentNode(0)
96, fCurrentEntity(0)
97, fDocument(0)
98, fDocumentType(0)
99, fDocumentVector(0)
100, fGrammarResolver(0)
101, fValidator(valToAdopt)
102, fMemoryManager(manager)
103, fGrammarPool(gramPool)
104, fBufMgr(manager)
105, fInternalSubset(fBufMgr.bidOnBuffer())
106, fPSVIHandler(0)
107{
108        CleanupType cleanup(this, &AbstractDOMParser::cleanUp);
109
110        try
111        {
112                initialize();
113        }
114        catch(const OutOfMemoryException&)
115        {
116                // Don't cleanup when out of memory, since executing the
117                // code can cause problems.
118                cleanup.release();
119
120                throw;
121        }
122
123        cleanup.release();
124}
125
126
127AbstractDOMParser::~AbstractDOMParser()
128{
129        cleanUp();
130}
131
132// ---------------------------------------------------------------------------
133//  AbstractDOMParser: Initialize/CleanUp methods
134// ---------------------------------------------------------------------------
135void AbstractDOMParser::initialize()
136{
137        //  Create grammar resolver and string pool to pass to the scanner
138        fGrammarResolver = new (fMemoryManager) GrammarResolver(fGrammarPool, fMemoryManager);
139
140        //  Create a scanner and tell it what validator to use. Then set us
141        //  as the document event handler so we can fill the DOM document.
142        fScanner = XMLScannerResolver::getDefaultScanner(fValidator, fGrammarResolver, fMemoryManager);
143        fScanner->setDocHandler(this);
144        fScanner->setDocTypeHandler(this);
145        this->reset();
146}
147
148void AbstractDOMParser::cleanUp()
149{
150        if (fDocumentVector)
151                delete fDocumentVector;
152
153        if (!fDocumentAdoptedByUser && fDocument)
154                fDocument->release();
155
156        delete fScanner;
157        delete fGrammarResolver;
158        // grammar pool *always* owns this
159        //delete fURIStringPool;
160        fMemoryManager->deallocate(fImplementationFeatures);
161
162        if (fValidator)
163                delete fValidator;
164}
165
166// ---------------------------------------------------------------------------
167//  AbstractDOMParser: Utilities
168// ---------------------------------------------------------------------------
169void AbstractDOMParser::reset()
170{
171        // if fDocument exists already, store the old pointer in the vector for deletion later
172        if (fDocument && !fDocumentAdoptedByUser) {
173                if (!fDocumentVector) {
174                        // allocate the vector if not exists yet
175                        fDocumentVector  = new (fMemoryManager) RefVectorOf<DOMDocumentImpl>(10, true, fMemoryManager) ;
176                }
177                fDocumentVector->addElement(fDocument);
178        }
179
180        fDocument = 0;
181        resetDocType();
182        fCurrentParent   = 0;
183        fCurrentNode     = 0;
184        fCurrentEntity   = 0;
185        fWithinElement   = false;
186        fDocumentAdoptedByUser = false;
187        fInternalSubset.reset();
188}
189
190
191void AbstractDOMParser::resetInProgress()
192{
193        fParseInProgress = false;
194}
195
196
197void AbstractDOMParser::resetPool()
198{
199        //  We cannot enter here while a regular parse is in progress.
200        if (fParseInProgress)
201                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
202
203        if (fDocumentVector)
204                fDocumentVector->removeAllElements();
205
206        if (!fDocumentAdoptedByUser && fDocument)
207                fDocument->release();
208
209        fDocument = 0;
210}
211
212bool AbstractDOMParser::isDocumentAdopted() const
213{
214        return fDocumentAdoptedByUser;
215}
216
217DOMDocument* AbstractDOMParser::adoptDocument()
218{
219        fDocumentAdoptedByUser = true;
220        return fDocument;
221}
222
223
224// ---------------------------------------------------------------------------
225//  AbstractDOMParser: Getter methods
226// ---------------------------------------------------------------------------
227DOMDocument* AbstractDOMParser::getDocument()
228{
229        return fDocument;
230}
231
232const XMLValidator& AbstractDOMParser::getValidator() const
233{
234        return *fScanner->getValidator();
235}
236
237bool AbstractDOMParser::getDoNamespaces() const
238{
239        return fScanner->getDoNamespaces();
240}
241
242bool AbstractDOMParser::getGenerateSyntheticAnnotations() const
243{
244        return fScanner->getGenerateSyntheticAnnotations();
245}
246
247bool AbstractDOMParser::getValidateAnnotations() const
248{
249        return fScanner->getValidateAnnotations();
250}
251
252bool AbstractDOMParser::getExitOnFirstFatalError() const
253{
254        return fScanner->getExitOnFirstFatal();
255}
256
257bool AbstractDOMParser::getValidationConstraintFatal() const
258{
259        return fScanner->getValidationConstraintFatal();
260}
261
262AbstractDOMParser::ValSchemes AbstractDOMParser::getValidationScheme() const
263{
264        const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
265
266        if (scheme == XMLScanner::Val_Always)
267                return Val_Always;
268        else if (scheme == XMLScanner::Val_Never)
269                return Val_Never;
270
271        return Val_Auto;
272}
273
274bool AbstractDOMParser::getDoSchema() const
275{
276        return fScanner->getDoSchema();
277}
278
279bool AbstractDOMParser::getValidationSchemaFullChecking() const
280{
281        return fScanner->getValidationSchemaFullChecking();
282}
283
284bool AbstractDOMParser::getIdentityConstraintChecking() const
285{
286        return fScanner->getIdentityConstraintChecking();
287}
288
289XMLSize_t AbstractDOMParser::getErrorCount() const
290{
291        return fScanner->getErrorCount();
292}
293
294XMLCh* AbstractDOMParser::getExternalSchemaLocation() const
295{
296        return fScanner->getExternalSchemaLocation();
297}
298
299XMLCh* AbstractDOMParser::getExternalNoNamespaceSchemaLocation() const
300{
301        return fScanner->getExternalNoNamespaceSchemaLocation();
302}
303
304SecurityManager* AbstractDOMParser::getSecurityManager() const
305{
306        return fScanner->getSecurityManager();
307}
308
309// Return it as a reference so that we cn return as void* from getParameter.
310//
311const XMLSize_t& AbstractDOMParser::getLowWaterMark() const
312{
313        return fScanner->getLowWaterMark();
314}
315
316bool AbstractDOMParser::getLoadExternalDTD() const
317{
318        return fScanner->getLoadExternalDTD();
319}
320
321bool AbstractDOMParser::getLoadSchema() const
322{
323        return fScanner->getLoadSchema();
324}
325
326bool AbstractDOMParser::getCalculateSrcOfs() const
327{
328        return fScanner->getCalculateSrcOfs();
329}
330
331bool AbstractDOMParser::getStandardUriConformant() const
332{
333        return fScanner->getStandardUriConformant();
334}
335
336bool AbstractDOMParser::getIgnoreAnnotations() const
337{
338        return fScanner->getIgnoreAnnotations();
339}
340
341bool AbstractDOMParser::getDisableDefaultEntityResolution() const
342{
343        return fScanner->getDisableDefaultEntityResolution();
344}
345
346bool AbstractDOMParser::getSkipDTDValidation() const
347{
348        return fScanner->getSkipDTDValidation();
349}
350
351bool AbstractDOMParser::getHandleMultipleImports() const
352{
353        return fScanner->getHandleMultipleImports();
354}
355
356// ---------------------------------------------------------------------------
357//  AbstractDOMParser: Setter methods
358// ---------------------------------------------------------------------------
359void AbstractDOMParser::setPSVIHandler(PSVIHandler* const handler)
360{
361        fPSVIHandler = handler;
362        if (fPSVIHandler) {
363                fScanner->setPSVIHandler(this);
364        }
365        else if(!fCreateSchemaInfo) {
366                fScanner->setPSVIHandler(0);
367        }
368}
369
370
371void AbstractDOMParser::setDoNamespaces(const bool newState)
372{
373        fScanner->setDoNamespaces(newState);
374}
375
376void AbstractDOMParser::setGenerateSyntheticAnnotations(const bool newState)
377{
378        fScanner->setGenerateSyntheticAnnotations(newState);
379}
380
381void AbstractDOMParser::setValidateAnnotations(const bool newState)
382{
383        fScanner->setValidateAnnotations(newState);
384}
385
386void AbstractDOMParser::setExitOnFirstFatalError(const bool newState)
387{
388        fScanner->setExitOnFirstFatal(newState);
389}
390
391void AbstractDOMParser::setValidationConstraintFatal(const bool newState)
392{
393        fScanner->setValidationConstraintFatal(newState);
394}
395
396void AbstractDOMParser::setValidationScheme(const ValSchemes newScheme)
397{
398        if (newScheme == Val_Never)
399                fScanner->setValidationScheme(XMLScanner::Val_Never);
400        else if (newScheme == Val_Always)
401                fScanner->setValidationScheme(XMLScanner::Val_Always);
402        else
403                fScanner->setValidationScheme(XMLScanner::Val_Auto);
404}
405
406void AbstractDOMParser::setDoSchema(const bool newState)
407{
408        fScanner->setDoSchema(newState);
409}
410
411void AbstractDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
412{
413        fScanner->setValidationSchemaFullChecking(schemaFullChecking);
414}
415
416void AbstractDOMParser::setIdentityConstraintChecking(const bool identityConstraintChecking)
417{
418        fScanner->setIdentityConstraintChecking(identityConstraintChecking);
419}
420
421void AbstractDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
422{
423        fScanner->setExternalSchemaLocation(schemaLocation);
424}
425void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
426{
427        fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
428}
429
430void AbstractDOMParser::setExternalSchemaLocation(const char* const schemaLocation)
431{
432        fScanner->setExternalSchemaLocation(schemaLocation);
433}
434void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
435{
436        fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
437}
438
439void AbstractDOMParser::setSecurityManager(SecurityManager* const securityManager)
440{
441        // since this could impact various components, don't permit it to change
442        // during a parse
443        if (fParseInProgress)
444                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
445
446        fScanner->setSecurityManager(securityManager);
447}
448
449void AbstractDOMParser::setLowWaterMark(XMLSize_t lwm)
450{
451        fScanner->setLowWaterMark(lwm);
452}
453
454void AbstractDOMParser::setLoadExternalDTD(const bool newState)
455{
456        fScanner->setLoadExternalDTD(newState);
457}
458
459void AbstractDOMParser::setLoadSchema(const bool newState)
460{
461        fScanner->setLoadSchema(newState);
462}
463
464void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
465{
466        fScanner->setCalculateSrcOfs(newState);
467}
468
469void AbstractDOMParser::setStandardUriConformant(const bool newState)
470{
471        fScanner->setStandardUriConformant(newState);
472}
473
474void AbstractDOMParser::useScanner(const XMLCh* const scannerName)
475{
476        XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
477        (
478                scannerName
479                , fValidator
480                , fGrammarResolver
481                , fMemoryManager
482        );
483
484        if (tempScanner)
485        {
486                tempScanner->setParseSettings(fScanner);
487                delete fScanner;
488                fScanner = tempScanner;
489        }
490}
491
492void AbstractDOMParser::setCreateSchemaInfo(const bool create)
493{
494        fCreateSchemaInfo = create;
495        if(fCreateSchemaInfo)
496                fScanner->setPSVIHandler(this);
497        else if(!fPSVIHandler)
498                fScanner->setPSVIHandler(0);
499}
500
501void AbstractDOMParser::setIgnoreAnnotations(const bool newValue)
502{
503        fScanner->setIgnoreAnnotations(newValue);
504}
505
506void AbstractDOMParser::setDisableDefaultEntityResolution(const bool newValue)
507{
508        fScanner->setDisableDefaultEntityResolution(newValue);
509}
510
511void AbstractDOMParser::setSkipDTDValidation(const bool newValue)
512{
513        fScanner->setSkipDTDValidation(newValue);
514}
515
516void AbstractDOMParser::setHandleMultipleImports(const bool newValue)
517{
518        fScanner->setHandleMultipleImports(newValue);
519}
520
521void AbstractDOMParser::setDocument(DOMDocument* toSet)
522{
523        fDocument = (DOMDocumentImpl *)toSet;
524}
525
526// ---------------------------------------------------------------------------
527//  AbstractDOMParser: Parsing methods
528// ---------------------------------------------------------------------------
529void AbstractDOMParser::parse(const InputSource& source)
530{
531        // Avoid multiple entrance
532        if (fParseInProgress)
533                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
534
535        ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);
536
537        try
538        {
539                fParseInProgress = true;
540                fScanner->scanDocument(source);
541
542                if (fDoXInclude && getErrorCount()==0){
543                        DOMDocument *doc = getDocument();
544                        // after XInclude, the document must be normalized
545                        if(doc)
546                                doc->normalizeDocument();
547                }
548        }
549        catch(const OutOfMemoryException&)
550        {
551                resetInProgress.release();
552
553                throw;
554        }
555}
556
557void AbstractDOMParser::parse(const XMLCh* const systemId)
558{
559        // Avoid multiple entrance
560        if (fParseInProgress)
561                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
562
563        ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);
564
565        try
566        {
567                fParseInProgress = true;
568                fScanner->scanDocument(systemId);
569
570                if (fDoXInclude && getErrorCount()==0){
571                        DOMDocument *doc = getDocument();
572                        // after XInclude, the document must be normalized
573                        if(doc)
574                                doc->normalizeDocument();
575                }
576        }
577        catch(const OutOfMemoryException&)
578        {
579                resetInProgress.release();
580
581                throw;
582        }
583}
584
585void AbstractDOMParser::parse(const char* const systemId)
586{
587        // Avoid multiple entrance
588        if (fParseInProgress)
589                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
590
591        ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);
592
593        try
594        {
595                fParseInProgress = true;
596                fScanner->scanDocument(systemId);
597
598                if (fDoXInclude && getErrorCount()==0){
599                        DOMDocument *doc = getDocument();
600                        // after XInclude, the document must be normalized
601                        if(doc)
602                                doc->normalizeDocument();
603                }
604        }
605        catch(const OutOfMemoryException&)
606        {
607                resetInProgress.release();
608
609                throw;
610        }
611}
612
613
614
615// ---------------------------------------------------------------------------
616//  AbstractDOMParser: Progressive parse methods
617// ---------------------------------------------------------------------------
618bool AbstractDOMParser::parseFirst( const XMLCh* const    systemId
619                                                                   ,       XMLPScanToken&  toFill)
620{
621        //
622        //  Avoid multiple entrance. We cannot enter here while a regular parse
623        //  is in progress.
624        //
625        if (fParseInProgress)
626                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
627
628        return fScanner->scanFirst(systemId, toFill);
629}
630
631bool AbstractDOMParser::parseFirst( const char* const         systemId
632                                                                   ,       XMLPScanToken&      toFill)
633{
634        //
635        //  Avoid multiple entrance. We cannot enter here while a regular parse
636        //  is in progress.
637        //
638        if (fParseInProgress)
639                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
640
641        return fScanner->scanFirst(systemId, toFill);
642}
643
644bool AbstractDOMParser::parseFirst( const InputSource& source
645                                                                   ,       XMLPScanToken&  toFill)
646{
647        //
648        //  Avoid multiple entrance. We cannot enter here while a regular parse
649        //  is in progress.
650        //
651        if (fParseInProgress)
652                ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
653
654        return fScanner->scanFirst(source, toFill);
655}
656
657bool AbstractDOMParser::parseNext(XMLPScanToken& token)
658{
659        return fScanner->scanNext(token);
660}
661
662void AbstractDOMParser::parseReset(XMLPScanToken& token)
663{
664        // Reset the scanner, and then reset the parser
665        fScanner->scanReset(token);
666        reset();
667}
668
669
670// ---------------------------------------------------------------------------
671//  AbstractDOMParser: Implementation of PSVIHandler interface
672// ---------------------------------------------------------------------------
673void AbstractDOMParser::handleElementPSVI(const XMLCh* const            localName
674                                                                                , const XMLCh* const            uri
675                                                                                ,       PSVIElement *           elementInfo)
676{
677        // associate the info now; if the user wants, she can override what we did
678        if(fCreateSchemaInfo)
679        {
680                DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
681                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, elementInfo->getValidity());
682                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validation_Attempted, elementInfo->getValidationAttempted());
683                if(elementInfo->getTypeDefinition())
684                {
685                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, elementInfo->getTypeDefinition()->getTypeCategory());
686                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, elementInfo->getTypeDefinition()->getAnonymous());
687                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace,
688                                fDocument->getPooledString(elementInfo->getTypeDefinition()->getNamespace()));
689                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name,
690                                fDocument->getPooledString(elementInfo->getTypeDefinition()->getName()));
691                }
692                else if(elementInfo->getValidity()==PSVIItem::VALIDITY_VALID)
693                {
694                        // if we are valid but we don't have a type validator, we are xs:anyType
695                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::COMPLEX_TYPE);
696                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
697                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
698                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgATTVAL_ANYTYPE);
699                }
700                if(elementInfo->getMemberTypeDefinition())
701                {
702                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, elementInfo->getMemberTypeDefinition()->getAnonymous());
703                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace,
704                                fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getNamespace()));
705                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name,
706                                fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getName()));
707                }
708                if(elementInfo->getElementDeclaration())
709                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Nil, elementInfo->getElementDeclaration()->getNillable());
710                typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(elementInfo->getSchemaDefault()));
711                typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(elementInfo->getSchemaNormalizedValue()));
712                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
713                ((DOMElementNSImpl*)fCurrentParent)->setSchemaTypeInfo(typeInfo);
714        }
715        if(fPSVIHandler)
716                fPSVIHandler->handleElementPSVI(localName, uri, elementInfo);
717}
718
719void AbstractDOMParser::handlePartialElementPSVI(const XMLCh* const            localName
720                                                                                           , const XMLCh* const            uri
721                                                                                           ,       PSVIElement *           elementInfo)
722{
723        if(fPSVIHandler)
724                fPSVIHandler->handlePartialElementPSVI(localName, uri, elementInfo);
725}
726
727void AbstractDOMParser::handleAttributesPSVI( const XMLCh* const            localName
728                                                                                        , const XMLCh* const            uri
729                                                                                        ,       PSVIAttributeList *     psviAttributes)
730{
731        if(fCreateSchemaInfo)
732        {
733                for (XMLSize_t index=0; index < psviAttributes->getLength(); index++) {
734                        XERCES_CPP_NAMESPACE_QUALIFIER PSVIAttribute *attrInfo=psviAttributes->getAttributePSVIAtIndex(index);
735                        XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* pAttrNode=fCurrentNode->getAttributes()->getNamedItemNS(psviAttributes->getAttributeNamespaceAtIndex(index),
736                                                                                                                                                                                                                        psviAttributes->getAttributeNameAtIndex(index));
737                        if(pAttrNode!=NULL)
738                        {
739                                DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
740                                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, attrInfo->getValidity());
741                                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validation_Attempted, attrInfo->getValidationAttempted());
742                                if(attrInfo->getTypeDefinition())
743                                {
744                                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
745                                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, attrInfo->getTypeDefinition()->getAnonymous());
746                                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace,
747                                                fDocument->getPooledString(attrInfo->getTypeDefinition()->getNamespace()));
748                                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name,
749                                                fDocument->getPooledString(attrInfo->getTypeDefinition()->getName()));
750                                }
751                                else if(attrInfo->getValidity()==PSVIItem::VALIDITY_VALID)
752                                {
753                                        // if we are valid but we don't have a type validator, we are xs:anySimpleType
754                                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
755                                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
756                                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
757                                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgDT_ANYSIMPLETYPE);
758                                }
759                                if(attrInfo->getMemberTypeDefinition())
760                                {
761                                        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, attrInfo->getMemberTypeDefinition()->getAnonymous());
762                                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace,
763                                                fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getNamespace()));
764                                        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name,
765                                                fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getName()));
766                                }
767                                typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(attrInfo->getSchemaDefault()));
768                                typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(attrInfo->getSchemaNormalizedValue()));
769                                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
770                                ((DOMAttrImpl*)pAttrNode)->setSchemaTypeInfo(typeInfo);
771                        }
772                }
773        }
774        // associate the info now; if the user wants, she can override what we did
775        if(fPSVIHandler)
776                fPSVIHandler->handleAttributesPSVI(localName, uri, psviAttributes);
777}
778
779// ---------------------------------------------------------------------------
780//  AbstractDOMParser: Implementation of XMLDocumentHandler interface
781// ---------------------------------------------------------------------------
782void AbstractDOMParser::docCharacters(  const   XMLCh* const    chars
783                                                          , const XMLSize_t    length
784                                                          , const bool         cdataSection)
785{
786        // Ignore chars outside of content
787        if (!fWithinElement)
788                return;
789
790        if (cdataSection == true)
791        {
792                DOMCDATASection *node = createCDATASection (chars, length);
793                castToParentImpl (fCurrentParent)->appendChildFast (node);
794                fCurrentNode = node;
795        }
796        else
797        {
798                if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
799                {
800                        DOMTextImpl *node = (DOMTextImpl*)fCurrentNode;
801                        node->appendData(chars, length);
802                }
803                else
804                {
805                        DOMText *node = createText (chars, length);
806                        castToParentImpl (fCurrentParent)->appendChildFast (node);
807                        fCurrentNode = node;
808                }
809        }
810}
811
812
813void AbstractDOMParser::docComment(const XMLCh* const comment)
814{
815        if (fCreateCommentNodes) {
816                DOMComment *dcom = fDocument->createComment(comment);
817                castToParentImpl (fCurrentParent)->appendChildFast (dcom);
818                fCurrentNode = dcom;
819        }
820}
821
822
823void AbstractDOMParser::docPI(  const   XMLCh* const    target
824                                          , const XMLCh* const    data)
825{
826        DOMProcessingInstruction *pi = fDocument->createProcessingInstruction
827                (
828                target
829                , data
830                );
831        castToParentImpl (fCurrentParent)->appendChildFast (pi);
832        fCurrentNode = pi;
833}
834
835
836void AbstractDOMParser::endEntityReference(const XMLEntityDecl&)
837{
838        if (!fCreateEntityReferenceNodes)
839          return;
840
841        DOMEntityReferenceImpl *erImpl = 0;
842
843        if (fCurrentParent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE)
844                erImpl = (DOMEntityReferenceImpl *) fCurrentParent;
845
846        fCurrentNode   = fCurrentParent;
847        fCurrentParent = fCurrentNode->getParentNode ();
848
849        // When the document is invalid but we continue parsing, we may
850        // end up seeing more 'end' events than the 'start' ones.
851        //
852        if (fCurrentParent == 0 && fDocument != 0)
853        {
854          fCurrentNode = fDocument->getDocumentElement ();
855          fCurrentParent = fCurrentNode;
856        }
857
858        if (erImpl)
859                erImpl->setReadOnly(true, true);
860}
861
862
863void AbstractDOMParser::endElement( const   XMLElementDecl&
864                                                   , const unsigned int
865                                                   , const bool
866                                                   , const XMLCh* const)
867{
868        fCurrentNode   = fCurrentParent;
869        fCurrentParent = fCurrentNode->getParentNode ();
870
871        // When the document is invalid but we continue parsing, we may
872        // end up seeing more 'end' events than the 'start' ones.
873        //
874        if (fCurrentParent == 0 && fDocument != 0)
875        {
876          fCurrentNode = fDocument->getDocumentElement ();
877          fCurrentParent = fCurrentNode;
878        }
879
880        // If we've hit the end of content, clear the flag.
881        //
882        if (fCurrentParent == fDocument)
883                fWithinElement = false;
884
885        if(fDoXInclude &&
886           (XIncludeUtils::isXIIncludeDOMNode(fCurrentNode) ||
887                ((XIncludeUtils::isXIFallbackDOMNode(fCurrentNode) &&
888                  !XMLString::equals(fCurrentParent->getNamespaceURI(), XIncludeUtils::fgXIIIncludeNamespaceURI)))))
889        {
890                XIncludeUtils xiu((XMLErrorReporter *) this);
891                // process the XInclude node, then update the fCurrentNode with the new content
892                if(xiu.parseDOMNodeDoingXInclude(fCurrentNode, fDocument, getScanner()->getEntityHandler()))
893                        fCurrentNode = fCurrentParent->getLastChild();
894        }
895}
896
897
898void AbstractDOMParser::ignorableWhitespace(  const XMLCh* const    chars
899                                                                                        , const XMLSize_t       length
900                                                                                        , const bool)
901{
902        // Ignore chars before the root element
903        if (!fWithinElement || !fIncludeIgnorableWhitespace)
904                return;
905
906        // revisit.  Not safe to slam in a null like this.
907        XMLCh savedChar = chars[length];
908        XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
909        ncChars[length] = chNull;
910
911        if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
912        {
913                DOMText *node = (DOMText *)fCurrentNode;
914                node->appendData(chars);
915        }
916        else
917        {
918                DOMTextImpl *node = (DOMTextImpl *)fDocument->createTextNode(chars);
919                node->setIgnorableWhitespace(true);
920                castToParentImpl (fCurrentParent)->appendChildFast (node);
921
922                fCurrentNode = node;
923        }
924        ncChars[length] = savedChar;
925}
926
927
928void AbstractDOMParser::resetDocument()
929{
930        //
931        //  The reset methods are called before a new parse event occurs.
932        //  Reset this parsers state to clear out anything that may be left
933        //  from a previous use, in particular the DOM document itself.
934        //
935        this->reset();
936}
937
938
939void AbstractDOMParser::startDocument()
940{
941        if(fImplementationFeatures == 0)
942                fDocument = (DOMDocumentImpl *)DOMImplementation::getImplementation()->createDocument(fMemoryManager);
943        else
944                fDocument = (DOMDocumentImpl *)DOMImplementationRegistry::getDOMImplementation(fImplementationFeatures)->createDocument(fMemoryManager);
945
946        // Just set the document as the current parent and current node
947        fCurrentParent = fDocument;
948        fCurrentNode   = fDocument;
949        // set DOM error checking off
950        fDocument->setErrorChecking(false);
951        fDocument->setDocumentURI(fScanner->getLocator()->getSystemId());
952        fDocument->setInputEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
953}
954
955
956void AbstractDOMParser::endDocument()
957{
958        // set DOM error checking back on
959        fDocument->setErrorChecking(true);
960
961        // DOM L2 does not support editing DocumentType nodes
962        if (fDocumentType && fScanner -> getDoNamespaces())
963                fDocumentType->setReadOnly(true, true);
964}
965
966
967void AbstractDOMParser::startElement(const XMLElementDecl&   elemDecl
968                                                         , const unsigned int            urlId
969                                                         , const XMLCh* const            elemPrefix
970                                                         , const RefVectorOf<XMLAttr>&   attrList
971                                                         , const XMLSize_t               attrCount
972                                                         , const bool                    isEmpty
973                                                         , const bool                    isRoot)
974{
975    DEBUG_MESSAGE("AbstractDOMParser::startElement(" << elemDecl << ',' << urlId << ',' << elemPrefix << ',' << attrList << ',' << attrCount << ',' << isEmpty << ',' << isRoot << ')');
976
977        DOMElement     *elem;
978        DOMElementImpl *elemImpl;
979        const XMLCh* namespaceURI = 0;
980        bool doNamespaces = fScanner->getDoNamespaces();
981
982        // Create the element name. Here we are going to bypass the
983        // DOMDocument::createElement() interface and instantiate the
984        // required types directly in order to avoid name checking
985        // overhead.
986        //
987        if (doNamespaces)
988        {
989                //DOM Level 2, doNamespaces on
990                //
991                const XMLCh* localName = elemDecl.getBaseName();
992
993                if (urlId != fScanner->getEmptyNamespaceId())
994                {
995                        namespaceURI = fScanner->getURIText(urlId); //get namespaceURI
996
997                        //                      if (elemPrefix && *elemPrefix)
998                        //                      {
999                        //                              XMLBufBid elemQName(&fBufMgr);
1000
1001                        //                              elemQName.set(elemPrefix);
1002                        //                              elemQName.append(chColon);
1003                        //                              elemQName.append(localName);
1004
1005                        //                              elem = createElementNS (
1006                        //                                namespaceURI, elemPrefix, localName, elemQName.getRawBuffer());
1007                        //                      }
1008                        //                      else
1009                        //                        elem = createElementNS (namespaceURI, 0, localName, localName);
1010
1011                        elem = createElementNS (namespaceURI, 0, localName, elemDecl.getFullName());
1012                }
1013                else
1014                {
1015                        elem = createElementNS (namespaceURI, 0, localName, localName);
1016                }
1017        }
1018        else
1019        {   //DOM Level 1
1020                elem = createElement (elemDecl.getFullName());
1021        }
1022
1023        elemImpl = (DOMElementImpl *) elem;
1024
1025        if (attrCount)
1026        {
1027                const unsigned int xmlnsNSId = XMLNamespaceResolver::fXMLNSUriId;
1028                const unsigned int emptyNSId = XMLNamespaceResolver::fEmptyUriId;
1029
1030                DOMAttrMapImpl* map = elemImpl->fAttributes;
1031                map->reserve (attrCount);
1032
1033                for (XMLSize_t index = 0; index < attrCount; ++index)
1034                {
1035                        const XMLAttr* attribute = attrList.elementAt(index);
1036                        DOMAttrImpl *attr = 0;
1037
1038                        if (doNamespaces)
1039                        {
1040                                //DOM Level 2, doNamespaces on
1041                                //
1042                                unsigned int attrURIId = attribute->getURIId();
1043                                const XMLCh* localName = attribute->getName();
1044                                const XMLCh* prefix = attribute->getPrefix();
1045                                namespaceURI = 0;
1046
1047                                if ((prefix==0 || *prefix==0) && XMLString::equals(localName, XMLUni::fgXMLNSString))
1048                                {
1049                                        // xmlns=...
1050                                        attrURIId = xmlnsNSId;
1051                                }
1052
1053                                if (attrURIId != emptyNSId)
1054                                {
1055                                        //TagName has a prefix
1056                                        namespaceURI = fScanner->getURIText(attrURIId);
1057                                }
1058
1059                                attr = (DOMAttrImpl*) createAttrNS (namespaceURI,
1060                                                                                                        prefix,
1061                                                                                                        localName,
1062                                                                                                        attribute->getQName());
1063
1064                                map->setNamedItemNSFast(attr);
1065                        }
1066                        else
1067                        {
1068                                attr = (DOMAttrImpl*) createAttr (attribute->getQName());
1069                                map->setNamedItemFast(attr);
1070                        }
1071
1072                        attr->setValueFast(attribute->getValue());
1073
1074                        // Attributes of type ID.  If this is one, add it to the hashtable of IDs
1075                        //   that is constructed for use by GetElementByID().
1076                        //
1077                        if (attribute->getType()==XMLAttDef::ID)
1078                        {
1079                                if (fDocument->fNodeIDMap == 0)
1080                                        fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument);
1081                                fDocument->fNodeIDMap->add(attr);
1082                                attr->fNode.isIdAttr(true);
1083                        }
1084
1085                        attr->setSpecified(attribute->getSpecified());
1086
1087                        // store DTD validation information
1088                        if(fCreateSchemaInfo)
1089                        {
1090                                switch(attribute->getType())
1091                                {
1092                                        case XMLAttDef::CData:          attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
1093                                        case XMLAttDef::ID:             attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
1094                                        case XMLAttDef::IDRef:          attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
1095                                        case XMLAttDef::IDRefs:         attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
1096                                        case XMLAttDef::Entity:         attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
1097                                        case XMLAttDef::Entities:       attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
1098                                        case XMLAttDef::NmToken:        attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
1099                                        case XMLAttDef::NmTokens:       attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
1100                                        case XMLAttDef::Notation:       attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
1101                                        case XMLAttDef::Enumeration:    attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
1102                                        default:                        attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
1103                                }
1104                        }
1105                }
1106        }
1107
1108        //Set up the default attributes if any.
1109        //
1110        if (elemDecl.hasAttDefs())
1111        {
1112                XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
1113                XMLAttDef* attr = 0;
1114                DOMAttrImpl * insertAttr = 0;
1115
1116                for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++)
1117                {
1118                        attr = &defAttrs->getAttDef(i);
1119
1120                        const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
1121                        if ((defType == XMLAttDef::Default) ||  (defType == XMLAttDef::Fixed))
1122                        {
1123                                if (doNamespaces)
1124                                {
1125                                        // DOM Level 2 wants all namespace declaration attributes
1126                                        // to be bound to "http://www.w3.org/2000/xmlns/"
1127                                        // So as long as the XML parser doesn't do it, it needs to
1128                                        // be done here.
1129                                        const XMLCh* qualifiedName = attr->getFullName();
1130                                        XMLBufBid bbPrefixQName(&fBufMgr);
1131                                        XMLBuffer& prefixBuf = bbPrefixQName.getBuffer();
1132                                        int colonPos = -1;
1133                                        unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos);
1134
1135                                        const XMLCh* namespaceURI = 0;
1136                                        if (XMLString::equals(qualifiedName, XMLUni::fgXMLNSString))    //for xmlns=...
1137                                                uriId = fScanner->getXMLNSNamespaceId();
1138                                        if (uriId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
1139                                                namespaceURI = fScanner->getURIText(uriId);
1140                                        }
1141
1142                                        insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(namespaceURI,     // NameSpaceURI
1143                                                                                                                                                          qualifiedName);   // qualified name
1144
1145                                        DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
1146                                        if (remAttr)
1147                                                remAttr->release();
1148                                }
1149                                else
1150                                {
1151                                        // Namespaces is turned off...
1152                                        insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
1153
1154                                        DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
1155                                        if (remAttr)
1156                                                remAttr->release();
1157                                }
1158                                //need to do this before the get as otherwise we overwrite any value in the attr
1159                                if (attr->getValue() != 0)
1160                                {
1161                                        insertAttr->setValueFast(attr->getValue());
1162                                        insertAttr->setSpecified(false);
1163                                }
1164
1165                                // store DTD validation information
1166                                if(fCreateSchemaInfo)
1167                                {
1168                                        switch(attr->getType())
1169                                        {
1170                                        case XMLAttDef::CData:          insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
1171                                        case XMLAttDef::ID:             insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
1172                                        case XMLAttDef::IDRef:          insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
1173                                        case XMLAttDef::IDRefs:         insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
1174                                        case XMLAttDef::Entity:         insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
1175                                        case XMLAttDef::Entities:       insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
1176                                        case XMLAttDef::NmToken:        insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
1177                                        case XMLAttDef::NmTokens:       insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
1178                                        case XMLAttDef::Notation:       insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
1179                                        case XMLAttDef::Enumeration:    insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
1180                                        default:                        insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
1181                                        }
1182                                }
1183                        }
1184
1185                        insertAttr = 0;
1186                        attr->reset();
1187                }
1188        }
1189
1190        if (fCurrentParent != fDocument)
1191                castToParentImpl (fCurrentParent)->appendChildFast (elem);
1192        else
1193                fCurrentParent->appendChild (elem);
1194
1195        fCurrentParent = elem;
1196        fCurrentNode = elem;
1197        fWithinElement = true;
1198
1199        // If an empty element, do end right now (no endElement() will be called)
1200        if (isEmpty)
1201                endElement(elemDecl, urlId, isRoot, elemPrefix);
1202}
1203
1204
1205void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
1206{
1207        const XMLCh * entName = entDecl.getName();
1208        DOMNamedNodeMap *entities = fDocumentType->getEntities();
1209        DOMEntityImpl* entity = (DOMEntityImpl*)entities->getNamedItem(entName);
1210        if (entity)
1211                entity->setInputEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
1212        fCurrentEntity = entity;
1213
1214
1215        // Following line has been moved up so that erImpl is only declared
1216        // and used if create entity ref flag is true
1217        if (fCreateEntityReferenceNodes == true)    {
1218                DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName);
1219
1220                //set the readOnly flag to false before appending node, will be reset
1221                // in endEntityReference
1222                DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er;
1223                erImpl->setReadOnly(false, true);
1224
1225                castToParentImpl (fCurrentParent)->appendChildFast (er);
1226
1227                fCurrentParent = er;
1228                fCurrentNode = er;
1229
1230        // this entityRef needs to be stored in Entity map too.
1231        // We'd decide later whether the entity nodes should be created by a
1232        // separated method in parser or not. For now just stick it in if
1233        // the ref nodes are created
1234                if (entity)
1235                        entity->setEntityRef(er);
1236        }
1237}
1238
1239
1240void AbstractDOMParser::XMLDecl(const   XMLCh* const version
1241                                                                , const XMLCh* const encoding
1242                                                                , const XMLCh* const standalone
1243                                                                , const XMLCh* const actualEncStr)
1244{
1245        fDocument->setXmlStandalone(XMLString::equals(XMLUni::fgYesString, standalone));
1246        fDocument->setXmlVersion(version);
1247        fDocument->setXmlEncoding(encoding);
1248        fDocument->setInputEncoding(actualEncStr);
1249}
1250
1251// ---------------------------------------------------------------------------
1252//  AbstractDOMParser: Helper methods
1253// ---------------------------------------------------------------------------
1254
1255//doctypehandler interfaces
1256void AbstractDOMParser::attDef
1257(
1258        const   DTDElementDecl&     elemDecl
1259        , const DTDAttDef&          attDef
1260        , const bool
1261)
1262{
1263        if (fDocumentType->isIntSubsetReading())
1264        {
1265                if (elemDecl.hasAttDefs())
1266                {
1267                        fInternalSubset.append(attDef.getFullName());
1268
1269                        // Get the type and display it
1270                        const XMLAttDef::AttTypes type = attDef.getType();
1271                        switch(type)
1272                        {
1273                        case XMLAttDef::CData :
1274                                fInternalSubset.append(chSpace);
1275                                fInternalSubset.append(XMLUni::fgCDATAString);
1276                                break;
1277                        case XMLAttDef::ID :
1278                                fInternalSubset.append(chSpace);
1279                                fInternalSubset.append(XMLUni::fgIDString);
1280                                break;
1281                        case XMLAttDef::IDRef :
1282                                fInternalSubset.append(chSpace);
1283                                fInternalSubset.append(XMLUni::fgIDRefString);
1284                                break;
1285                        case XMLAttDef::IDRefs :
1286                                fInternalSubset.append(chSpace);
1287                                fInternalSubset.append(XMLUni::fgIDRefsString);
1288                                break;
1289                        case XMLAttDef::Entity :
1290                                fInternalSubset.append(chSpace);
1291                                fInternalSubset.append(XMLUni::fgEntityString);
1292                                break;
1293                        case XMLAttDef::Entities :
1294                                fInternalSubset.append(chSpace);
1295                                fInternalSubset.append(XMLUni::fgEntitiesString);
1296                                break;
1297                        case XMLAttDef::NmToken :
1298                                fInternalSubset.append(chSpace);
1299                                fInternalSubset.append(XMLUni::fgNmTokenString);
1300                                break;
1301                        case XMLAttDef::NmTokens :
1302                                fInternalSubset.append(chSpace);
1303                                fInternalSubset.append(XMLUni::fgNmTokensString);
1304                                break;
1305
1306                        case XMLAttDef::Notation :
1307                                fInternalSubset.append(chSpace);
1308                                fInternalSubset.append(XMLUni::fgNotationString);
1309                                break;
1310
1311                        case XMLAttDef::Enumeration :
1312                                {
1313                                        fInternalSubset.append(chSpace);
1314                                        const XMLCh* enumString = attDef.getEnumeration();
1315                                        XMLSize_t length = XMLString::stringLen(enumString);
1316                                        if (length > 0) {
1317
1318                                                fInternalSubset.append(chOpenParen );
1319                                                for(XMLSize_t i=0; i<length; i++) {
1320                                                        if (enumString[i] == chSpace)
1321                                                                fInternalSubset.append(chPipe);
1322                                                        else
1323                                                                fInternalSubset.append(enumString[i]);
1324                                                }
1325                                                fInternalSubset.append(chCloseParen);
1326                                        }
1327                                }
1328                                break;
1329                        default:
1330                                // remaining types don't belong to a DTD
1331                                break;
1332                        }
1333                        //get te default types of the attlist
1334                        const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
1335                        switch(def)
1336                        {
1337                        case XMLAttDef::Required :
1338                                fInternalSubset.append(chSpace);
1339                                fInternalSubset.append(XMLUni::fgRequiredString);
1340                                break;
1341                        case XMLAttDef::Implied :
1342                                fInternalSubset.append(chSpace);
1343                                fInternalSubset.append(XMLUni::fgImpliedString);
1344                                break;
1345                        case XMLAttDef::Fixed :
1346                                fInternalSubset.append(chSpace);
1347                                fInternalSubset.append(XMLUni::fgFixedString);
1348                                break;
1349                        default:
1350                                // remaining types don't belong to a DTD
1351                                break;
1352                        }
1353
1354                        const XMLCh* defaultValue = attDef.getValue();
1355                        if (defaultValue != 0) {
1356                                fInternalSubset.append(chSpace);
1357                                fInternalSubset.append(chDoubleQuote);
1358                                fInternalSubset.append(defaultValue);
1359                                fInternalSubset.append(chDoubleQuote);
1360                        }
1361                }
1362        }
1363}
1364
1365void AbstractDOMParser::doctypeComment
1366(
1367        const   XMLCh* const    comment
1368)
1369{
1370        if (fDocumentType->isIntSubsetReading())
1371        {
1372                if (comment != 0)
1373                {
1374                        fInternalSubset.append(XMLUni::fgCommentString);
1375                        fInternalSubset.append(chSpace);
1376                        fInternalSubset.append(comment);
1377                        fInternalSubset.append(chSpace);
1378                        fInternalSubset.append(chDash);
1379                        fInternalSubset.append(chDash);
1380                        fInternalSubset.append(chCloseAngle);
1381                }
1382        }
1383}
1384
1385void AbstractDOMParser::doctypeDecl
1386(
1387        const   DTDElementDecl& elemDecl
1388        , const XMLCh* const    publicId
1389        , const XMLCh* const    systemId
1390        , const bool
1391        , const bool
1392)
1393{
1394        fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
1395        fDocument->setDocumentType(fDocumentType);
1396
1397}
1398
1399void AbstractDOMParser::doctypePI
1400(
1401        const   XMLCh* const    target
1402        , const XMLCh* const    data
1403)
1404{
1405        if (fDocumentType->isIntSubsetReading())
1406        {
1407                //add these chars to internalSubset variable
1408                fInternalSubset.append(chOpenAngle);
1409                fInternalSubset.append(chQuestion);
1410                fInternalSubset.append(target);
1411                fInternalSubset.append(chSpace);
1412                fInternalSubset.append(data);
1413                fInternalSubset.append(chQuestion);
1414                fInternalSubset.append(chCloseAngle);
1415        }
1416}
1417
1418
1419void AbstractDOMParser::doctypeWhitespace
1420(
1421        const   XMLCh* const    chars
1422        , const XMLSize_t       length
1423)
1424{
1425        if (fDocumentType->isIntSubsetReading())
1426                fInternalSubset.append(chars, length);
1427}
1428
1429void AbstractDOMParser::elementDecl
1430(
1431        const   DTDElementDecl& decl
1432        , const bool
1433)
1434{
1435        if (fDocumentType->isIntSubsetReading())
1436        {
1437                fInternalSubset.append(chOpenAngle);
1438                fInternalSubset.append(chBang);
1439                fInternalSubset.append(XMLUni::fgElemString);
1440                fInternalSubset.append(chSpace);
1441                fInternalSubset.append(decl.getFullName());
1442
1443                //get the ContentSpec information
1444                const XMLCh* contentModel = decl.getFormattedContentModel();
1445                if (contentModel != 0) {
1446                        fInternalSubset.append(chSpace);
1447                        fInternalSubset.append(contentModel);
1448                }
1449
1450                fInternalSubset.append(chCloseAngle);
1451        }
1452}
1453
1454void AbstractDOMParser::endAttList
1455(
1456        const   DTDElementDecl& elemDecl
1457)
1458{
1459        if (fDocumentType->isIntSubsetReading())
1460        {
1461                //print the closing angle
1462                fInternalSubset.append(chCloseAngle);
1463        }
1464
1465        // this section sets up default attributes.
1466        // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
1467        // default attribute data attached to the document is used to conform to the
1468        // DOM spec regarding creating element nodes & removing attributes with default values
1469        // see DocumentTypeImpl
1470        if (elemDecl.hasAttDefs())
1471        {
1472                XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
1473                XMLAttDef* attr = 0;
1474
1475                DOMAttrImpl * insertAttr = 0;
1476                DOMElement     *elem  = fDocument->createElement(elemDecl.getFullName());
1477                DOMElementImpl *elemImpl = (DOMElementImpl *) elem;
1478                bool doNamespaces = fScanner->getDoNamespaces();
1479
1480                for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++)
1481                {
1482                        attr = &defAttrs->getAttDef(i);
1483                        if (attr->getValue() != 0)
1484                        {
1485                                if (doNamespaces)
1486                                {
1487                                        // DOM Level 2 wants all namespace declaration attributes
1488                                        // to be bound to "http://www.w3.org/2000/xmlns/"
1489                                        // So as long as the XML parser doesn't do it, it needs to
1490                                        // done here.
1491                                        const XMLCh* qualifiedName = attr->getFullName();
1492                                        int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
1493
1494                                        XMLBufBid bbQName(&fBufMgr);
1495                                        XMLBuffer& buf = bbQName.getBuffer();
1496                                        static const XMLCh XMLNS[] = {
1497                                                chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};
1498
1499                                        if (index > 0) {
1500                                                // there is prefix
1501                                                // map to XML URI for all cases except when prefix == "xmlns"
1502                                                XMLCh* prefix;
1503                                                XMLCh temp[1000];
1504
1505                                                if (index > 999)
1506                                                        prefix = (XMLCh*) fMemoryManager->allocate
1507                                                        (
1508                                                                (index + 1) * sizeof(XMLCh)
1509                                                        );//new XMLCh[index+1];
1510                                                else
1511                                                        prefix = temp;
1512
1513                                                XMLString::subString(prefix ,qualifiedName, 0, index, fMemoryManager);
1514
1515                                                if (XMLString::equals(prefix,XMLNS))
1516                                                        buf.append(XMLUni::fgXMLNSURIName);
1517                                                else
1518                                                        buf.append(XMLUni::fgXMLURIName);
1519
1520                                                if (index > 999)
1521                                                        fMemoryManager->deallocate(prefix);//delete [] prefix;
1522                                        }
1523                                        else {
1524                                                //   No prefix
1525                                                if (XMLString::equals(qualifiedName,XMLNS))
1526                                                        buf.append(XMLUni::fgXMLNSURIName);
1527                                        }
1528
1529                                        insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
1530                                           buf.getRawBuffer(),     // NameSpaceURI
1531                                           qualifiedName);   // qualified name
1532
1533                                        DOMNode* remAttr = elemImpl->setAttributeNodeNS(insertAttr);
1534                                        if (remAttr)
1535                                                remAttr->release();
1536                                }
1537                                else
1538                                {
1539                                        // Namespaces is turned off...
1540                                        insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
1541                                        DOMNode* remAttr = elemImpl->setAttributeNode(insertAttr);
1542                                        if (remAttr)
1543                                                remAttr->release();
1544                                }
1545
1546                                insertAttr->setValueFast(attr->getValue());
1547                                insertAttr->setSpecified(false);
1548                        }
1549                }
1550                DOMNode* rem = fDocumentType->getElements()->setNamedItem(elemImpl);
1551                if (rem)
1552                        rem->release();
1553        }
1554}
1555
1556void AbstractDOMParser::endIntSubset()
1557{
1558        fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
1559        // the buffer shouldn't be released as it is reused in the next parse
1560        // fBufMgr.releaseBuffer(fInternalSubset);
1561        fDocumentType->fIntSubsetReading = false;
1562}
1563
1564void AbstractDOMParser::endExtSubset()
1565{
1566}
1567
1568void AbstractDOMParser::entityDecl
1569(
1570        const   DTDEntityDecl&  entityDecl
1571        , const bool
1572        , const bool
1573)
1574{
1575        DOMEntityImpl* entity = (DOMEntityImpl *) fDocument->createEntity(entityDecl.getName());
1576
1577        entity->setPublicId(entityDecl.getPublicId());
1578        entity->setSystemId(entityDecl.getSystemId());
1579        entity->setNotationName(entityDecl.getNotationName());
1580        entity->setBaseURI(entityDecl.getBaseURI());
1581
1582        DOMEntityImpl *previousDef = (DOMEntityImpl *)
1583                fDocumentType->getEntities()->setNamedItem( entity );
1584
1585        if (previousDef)
1586                previousDef->release();
1587
1588        if (fDocumentType->isIntSubsetReading())
1589        {
1590                //add thes chars to internalSubset variable
1591                fInternalSubset.append(chOpenAngle);
1592                fInternalSubset.append(chBang);
1593                fInternalSubset.append(XMLUni::fgEntityString);
1594                fInternalSubset.append(chSpace);
1595
1596                fInternalSubset.append(entityDecl.getName());
1597
1598                const XMLCh* id = entity->getPublicId();
1599                if (id != 0) {
1600                        fInternalSubset.append(chSpace);
1601                        fInternalSubset.append(XMLUni::fgPubIDString);
1602                        fInternalSubset.append(chSpace);
1603                        fInternalSubset.append(chDoubleQuote);
1604                        fInternalSubset.append(id);
1605                        fInternalSubset.append(chDoubleQuote);
1606                }
1607                id = entity->getSystemId();
1608                if (id != 0) {
1609                        fInternalSubset.append(chSpace);
1610                        fInternalSubset.append(XMLUni::fgSysIDString);
1611                        fInternalSubset.append(chSpace);
1612                        fInternalSubset.append(chDoubleQuote);
1613                        fInternalSubset.append(id);
1614                        fInternalSubset.append(chDoubleQuote);
1615
1616                }
1617                id = entity->getNotationName();
1618                if (id != 0) {
1619                        fInternalSubset.append(chSpace);
1620                        fInternalSubset.append(XMLUni::fgNDATAString);
1621                        fInternalSubset.append(chSpace);
1622                        fInternalSubset.append(id);
1623                }
1624                id = entityDecl.getValue();
1625                if (id !=0) {
1626                        fInternalSubset.append(chSpace);
1627                        fInternalSubset.append(chDoubleQuote);
1628                        fInternalSubset.append(id);
1629                        fInternalSubset.append(chDoubleQuote);
1630                }
1631
1632                fInternalSubset.append(chCloseAngle);
1633        }
1634
1635}
1636
1637void AbstractDOMParser::resetDocType()
1638{
1639        fDocumentType = 0;
1640}
1641
1642void AbstractDOMParser::notationDecl
1643(
1644        const   XMLNotationDecl&    notDecl
1645        , const bool
1646)
1647{
1648        DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName());
1649        notation->setPublicId(notDecl.getPublicId());
1650        notation->setSystemId(notDecl.getSystemId());
1651        notation->setBaseURI(notDecl.getBaseURI());
1652
1653        DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation );
1654        if (rem)
1655                rem->release();
1656
1657        if (fDocumentType->isIntSubsetReading())
1658        {
1659                //add thes chars to internalSubset variable
1660                fInternalSubset.append(chOpenAngle);
1661                fInternalSubset.append(chBang);
1662                fInternalSubset.append(XMLUni::fgNotationString);
1663                fInternalSubset.append(chSpace);
1664
1665                fInternalSubset.append(notDecl.getName());
1666
1667                const XMLCh* id = notation->getPublicId();
1668                if (id != 0) {
1669                        fInternalSubset.append(chSpace);
1670                        fInternalSubset.append(XMLUni::fgPubIDString);
1671                        fInternalSubset.append(chSpace);
1672                        fInternalSubset.append(chDoubleQuote);
1673                        fInternalSubset.append(id);
1674                        fInternalSubset.append(chDoubleQuote);
1675                }
1676                id = notation->getSystemId();
1677                if (id != 0) {
1678                        fInternalSubset.append(chSpace);
1679                        fInternalSubset.append(XMLUni::fgSysIDString);
1680                        fInternalSubset.append(chSpace);
1681                        fInternalSubset.append(chDoubleQuote);
1682                        fInternalSubset.append(id);
1683                        fInternalSubset.append(chDoubleQuote);
1684
1685                }
1686                fInternalSubset.append(chCloseAngle);
1687        }
1688}
1689
1690void AbstractDOMParser::startAttList
1691(
1692        const   DTDElementDecl& elemDecl
1693)
1694{
1695        if (fDocumentType->isIntSubsetReading())
1696        {
1697                fInternalSubset.append(chOpenAngle);
1698                fInternalSubset.append(chBang);
1699                fInternalSubset.append(XMLUni::fgAttListString);
1700                fInternalSubset.append(chSpace);
1701                fInternalSubset.append(elemDecl.getFullName());
1702        }
1703}
1704
1705void AbstractDOMParser::startIntSubset()
1706{
1707        fDocumentType->fIntSubsetReading = true;
1708}
1709
1710void AbstractDOMParser::startExtSubset()
1711{
1712}
1713
1714void AbstractDOMParser::TextDecl
1715(
1716        const   XMLCh* const    versionStr
1717        , const XMLCh* const    encodingStr
1718)
1719{
1720        if (fCurrentEntity) {
1721                fCurrentEntity->setXmlVersion(versionStr);
1722                fCurrentEntity->setXmlEncoding(encodingStr);
1723        }
1724}
1725
1726DOMCDATASection* AbstractDOMParser::
1727createCDATASection (const XMLCh* s, XMLSize_t n)
1728{
1729  return new (fDocument, DOMMemoryManager::CDATA_SECTION_OBJECT)
1730        DOMCDATASectionImpl(fDocument, s, n);
1731}
1732
1733
1734DOMText* AbstractDOMParser::
1735createText (const XMLCh* s, XMLSize_t n)
1736{
1737  return new (fDocument, DOMMemoryManager::TEXT_OBJECT)
1738        DOMTextImpl(fDocument, s, n);
1739}
1740
1741
1742DOMElement* AbstractDOMParser::
1743createElement (const XMLCh* name)
1744{
1745  return new (fDocument, DOMMemoryManager::ELEMENT_OBJECT)
1746        DOMElementImpl(fDocument, name);
1747}
1748
1749DOMElement* AbstractDOMParser::
1750createElementNS (const XMLCh* namespaceURI,
1751                                 const XMLCh* elemPrefix,
1752                                 const XMLCh* localName,
1753                                 const XMLCh* qName)
1754{
1755  return new (fDocument, DOMMemoryManager::ELEMENT_NS_OBJECT)
1756        DOMElementNSImpl (fDocument,
1757                                          namespaceURI,
1758                                          elemPrefix,
1759                                          localName,
1760                                          qName);
1761}
1762
1763DOMAttr* AbstractDOMParser::
1764createAttr (const XMLCh* name)
1765{
1766  return new (fDocument, DOMMemoryManager::ATTR_OBJECT)
1767        DOMAttrImpl(fDocument, name);
1768}
1769
1770DOMAttr* AbstractDOMParser::
1771createAttrNS (const XMLCh* namespaceURI,
1772                          const XMLCh* elemPrefix,
1773                          const XMLCh* localName,
1774                          const XMLCh* qName)
1775{
1776  return new (fDocument, DOMMemoryManager::ATTR_NS_OBJECT)
1777        DOMAttrNSImpl (fDocument,
1778                                   namespaceURI,
1779                                   elemPrefix,
1780                                   localName,
1781                                   qName);
1782}
1783
1784XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.