Xalan-C++ API Reference 1.12.0
StylesheetHandler.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#if !defined(XALAN_STYLESHEETHANDLER_HEADER_GUARD)
20#define XALAN_STYLESHEETHANDLER_HEADER_GUARD
21
22// Base include file. Must be first.
23#include "XSLTDefinitions.hpp"
24
25
26
29
30
31
33
34
35
37
38
39
41
42
43
48
49
50
51namespace XALAN_CPP_NAMESPACE {
52
53
54
55class ElemTemplate;
56class ElemTemplateElement;
57class ElemTextLiteral;
58class ExtensionNSHandler;
59class StylesheetConstructionContext;
60
61
62
63/**
64 * This class processes a stylesheet via SAX events, and inits
65 * the given stylesheet. If you need to alter the code in here,
66 * it is not for the faint-of-heart, due to the state tracking
67 * that has to be done due to the SAX event model.
68 */
70{
71
72public:
73
76
81
82 /**
83 * Perform static initialization. See class XMLSupportInit.
84 */
85 static void
86 initialize(MemoryManager& theManager);
87
88 /**
89 * Perform static shut down. See class XMLSupportInit.
90 */
91 static void
93
94 /**
95 * Construct a StylesheetHandler ... it will add the DOM nodes
96 * to the document fragment.
97 */
101
102 MemoryManager&
104 {
105 return m_constructionContext.getMemoryManager();
106 }
107
108 virtual
110
111 /**
112 * Receive notification of character data.
113 *
114 * <p>The Parser will call this method to report each chunk of
115 * character data. SAX parsers may return all contiguous character
116 * data in a single chunk, or they may split it into several
117 * chunks; however, all of the characters in any single event
118 * must come from the same external entity, so that the Locator
119 * provides useful information.</p>
120 *
121 * <p>The application must not attempt to read from the array
122 * outside of the specified range.</p>
123 *
124 * <p>Note that some parsers will report whitespace using the
125 * ignorableWhitespace() method rather than this one (validating
126 * parsers must do so).</p>
127 *
128 * @param chars pointer to characters from the XML document
129 * @param length number of characters to read from the array
130 * @exception SAXException
131 * @see #ignorableWhitespace
132 * @see org.xml.sax.Locator
133 */
134 virtual void
136 const XMLCh* const chars,
137 const size_type length);
138
139 /**
140 * Receive notification of character data. If available, when the
141 * disable-output-escaping attribute is used, output raw text without
142 * escaping.
143 *
144 * @param ch pointer to characters from the XML document
145 * @param start start position in the array
146 * @param length number of characters to read from the array
147 * @exception SAXException
148 */
149 virtual void
151 const XMLCh* const chars,
152 const size_type length);
153
154 /**
155 * Receive notification of cdata.
156 *
157 * <p>The Parser will call this method to report each chunk of
158 * character data. SAX parsers may return all contiguous character
159 * data in a single chunk, or they may split it into several
160 * chunks; however, all of the characters in any single event
161 * must come from the same external entity, so that the Locator
162 * provides useful information.</p>
163 *
164 * <p>The application must not attempt to read from the array
165 * outside of the specified range.</p>
166 *
167 * <p>Note that some parsers will report whitespace using the
168 * ignorableWhitespace() method rather than this one (validating
169 * parsers must do so).</p>
170 *
171 * @param ch pointer to characters from the XML document
172 * @param start start position in the array
173 * @param length number of characters to read from the array
174 * @exception SAXException
175 * @see #ignorableWhitespace
176 */
177 virtual void
179 const XMLCh* const ch,
180 const size_type length);
181
182 /**
183 * Receive notification of ignorable whitespace in element content.
184 *
185 * <p>Validating Parsers must use this method to report each chunk
186 * of ignorable whitespace (see the W3C XML 1.0 recommendation,
187 * section 2.10): non-validating parsers may also use this method
188 * if they are capable of parsing and using content models.</p>
189 *
190 * <p>SAX parsers may return all contiguous whitespace in a single
191 * chunk, or they may split it into several chunks; however, all of
192 * the characters in any single event must come from the same
193 * external entity, so that the Locator provides useful
194 * information.</p>
195 *
196 * <p>The application must not attempt to read from the array
197 * outside of the specified range.</p>
198 *
199 * @param chars characters from the XML document
200 * @param start start position in the array
201 * @param length number of characters to read from the array
202 * @exception SAXException
203 * @see #characters
204 */
205 virtual void
207 const XMLCh* const chars,
208 const size_type length);
209
210 /**
211 * Receive notification of a processing instruction.
212 *
213 * <p>The Parser will invoke this method once for each processing
214 * instruction found: note that processing instructions may occur
215 * before or after the main document element.</p>
216 *
217 * <p>A SAX parser should never report an XML declaration (XML 1.0,
218 * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
219 * using this method.</p>
220 *
221 * @param target pointer to processing instruction target
222 * @param data pointer to processing instruction data, or null if none
223 * was supplied
224 * @exception SAXException
225 */
226 virtual void processingInstruction (const XMLCh* const target, const XMLCh* const data);
227
228 /**
229 * Called when a Comment is to be constructed.
230 *
231 * @param data comment data
232 * @exception SAXException
233 */
234 virtual void comment(const XMLCh* const data);
235
236 /**
237 * Receive notification of a entityReference.
238 *
239 * @param data pointer to characters from the XML document
240 * @exception SAXException
241 */
242 virtual void entityReference(const XMLCh* const data);
243
244 // These methods are inherited DocumentHandler ...
245
246 // $$$ Theoretically, shouldn't need javadoc for these, since they are
247 // inherited from DocumentHandler, but let's leave them in for now -- JMD
248
249 /**
250 * Receive an object for locating the origin of SAX document events.
251 *
252 * <p>SAX parsers are strongly encouraged (though not absolutely
253 * required) to supply a locator: if it does so, it must supply
254 * the locator to the application by invoking this method before
255 * invoking any of the other methods in the DocumentHandler
256 * interface.</p>
257 *
258 * <p>The locator allows the application to determine the end
259 * position of any document-related event, even if the parser is
260 * not reporting an error. Typically, the application will
261 * use this information for reporting its own errors (such as
262 * character content that does not match an application's
263 * business rules). The information returned by the locator
264 * is probably not sufficient for use with a search engine.</p>
265 *
266 * <p>Note that the locator will return correct information only
267 * during the invocation of the events in this interface. The
268 * application should not attempt to use it at any other time.</p>
269 *
270 * @param locator object that can return the location of
271 * any SAX document event.
272 * @see org.xml.sax.Locator
273 */
274 virtual void setDocumentLocator(const Locator* const locator);
275
276 /**
277 * Receive notification of the beginning of a document.
278 *
279 * <p>The SAX parser will invoke this method only once, before any
280 * other methods in this interface or in DTDHandler (except for
281 * setDocumentLocator).</p>
282 *
283 * @exception SAXException
284 */
285 virtual void startDocument();
286
287 /**
288 * Receive notification of the end of a document.
289 *
290 * <p>The SAX parser will invoke this method only once, and it will
291 * be the last method invoked during the parse. The parser shall
292 * not invoke this method until it has either abandoned parsing
293 * (because of an unrecoverable error) or reached the end of
294 * input.</p>
295 *
296 * @exception SAXException
297 */
298 virtual void endDocument();
299
300 /**
301 * Receive notification of the beginning of an element.
302 *
303 * <p>The Parser will invoke this method at the beginning of every
304 * element in the XML document; there will be a corresponding
305 * endElement() event for every startElement() event (even when the
306 * element is empty). All of the element's content will be
307 * reported, in order, before the corresponding endElement()
308 * event.</p>
309 *
310 * <p>If the element name has a namespace prefix, the prefix will
311 * still be attached. Note that the attribute list provided will
312 * contain only attributes with explicit values (specified or
313 * defaulted): #IMPLIED attributes will be omitted.</p>
314 *
315 * @param name element type name
316 * @param atts attributes attached to the element, if any
317 * @exception SAXException
318 * @see #endElement
319 * @see org.xml.sax.AttributeList
320 */
321 virtual void startElement(const XMLCh* const name, AttributeListType& attrs);
322
323 /**
324 * Receive notification of the end of an element.
325 *
326 * <p>The SAX parser will invoke this method at the end of every
327 * element in the XML document; there will be a corresponding
328 * startElement() event for every endElement() event (even when the
329 * element is empty).</p>
330 *
331 * <p>If the element name has a namespace prefix, the prefix will
332 * still be attached to the name.</p>
333 *
334 * @param name element type name
335 * @exception SAXException
336 */
337 virtual void endElement(const XMLCh* const name);
338
339 /**
340 * This method allows the user installed Document Handler to 'reset'
341 * itself, freeing all the memory resources. The scanner calls this
342 * method before starting a new parse event.
343 */
344 virtual void resetDocument();
345
346protected:
347
348 /**
349 * See if this is a xmlns attribute, and, if so, process it.
350 *
351 * @param attrName Qualified name of attribute.
352 * @param atts The attribute list where the element comes from (not used at
353 * this time).
354 * @param which The index into the attribute list (not used at this time).
355 * @return True if this is a namespace name.
356 */
357 bool
359 const XalanDOMChar* attrName,
360 const AttributeListType& atts,
362
363 /**
364 * Tell whether or not this is a xml:space attribute and, if so, process it.
365 *
366 * @param elementName The name of the element that owns the attribute
367 * @param aname The name of the attribute in question.
368 * @param atts The attribute list that owns the attribute.
369 * @param which The index of the attribute into the attribute list.
370 * @param locator A Locator instance for error reporting.
371 * @param fPreserve set to true if the attribute value is "preserve"
372 * @return True if this is a xml:space attribute.
373 */
374 bool
377 const XalanDOMChar* aname,
378 const AttributeListType& atts,
380 const Locator* locator,
381 bool& fPreserve);
382
383 /**
384 * Tell whether or not this is a xml:space attribute and, if so, process it.
385 *
386 * @param elementName The name of the element that owns the attributes
387 * @param atts The attribute list that owns the attribute.
388 * @param locator A Locator instance for error reporting.
389 * @param fPreserve set to true if an xml:space attribute value is "preserve"
390 * @return True if this is a xml:space attribute.
391 */
392 bool
395 const AttributeListType& atts,
396 const Locator* locator,
397 bool& fPreserve);
398
399 /**
400 * Process xsl:import.
401 */
402 void
404 const XalanDOMChar* name,
405 const AttributeListType& atts,
406 const Locator* locator);
407
408 /**
409 * Process xsl:include.
410 */
411 void
413 const XalanDOMChar* name,
414 const AttributeListType& atts,
415 const Locator* locator);
416
417 void
419
420private:
421
422 enum { eElemEmptyAllocatorBlockSize = 10, eElemTextBlockSize = 10 };
423
424 // not implemented
426
428 operator=(const StylesheetHandler&);
429
430 // Utility functions...
431 void
432 illegalAttributeError(
435 const Locator* theLocator) const;
436
437 void
438 error(
441 const Locator* theLocator) const;
442
443 void
444 error(
447 const Locator* theLocator) const;
448
449 void
450 error(
453 const Locator* theLocator) const;
454
455 void
456 error(
459 const Locator* theLocator) const;
460
461 void
462 warn(
465 const Locator* theLocator) const;
466
467 void
468 warn(
471 const Locator* theLocator) const;
472 void
473 warn(
475 const Locator* theLocator) const;
476
477 void
478 error(
480 const Locator* theLocator) const;
481
482 void
483 processText(
484 const XMLCh* chars,
485 size_type length);
486
487 void
488 accumulateText(
489 const XMLCh* chars,
490 size_type length);
491
492 void
493 processAccumulatedText();
494
495 void
496 processTopLevelElement(
497 const XalanDOMChar* name,
498 const AttributeListType& atts,
499 int xslToken,
500 const Locator* locator,
501 bool& fPreserveSpace,
502 bool& fSpaceAttrProcessed);
503
504 void
505 processStylesheet(
506 const XalanDOMChar* name,
507 const AttributeListType& atts,
508 const Locator* locator,
509 bool& fPreserveSpace,
510 bool& fSpaceAttrProcessed);
511
512 void
513 processPreserveStripSpace(
514 const XalanDOMChar* name,
515 const AttributeListType& atts,
516 const Locator* locator,
517 int xslToken);
518
519 void
520 appendChildElementToParent(
522 const Locator* locator);
523
524 void
525 appendChildElementToParent(
528
529 void
530 appendChildElementToParent(
533 const Locator* locator);
534
535 bool
536 inExtensionElement() const;
537
538 void
539 processExtensionElement(
540 const XalanDOMChar* name,
542 const AttributeListType& atts,
543 const Locator* locator);
544
545 void
546 checkForOrAddVariableName(
548 const Locator* theLocator);
549
550 // Data members...
551
552 /**
553 * The owning stylesheet.
554 */
555 Stylesheet& m_stylesheet;
556
557 /**
558 * The construction context.
559 */
560 StylesheetConstructionContext& m_constructionContext;
561
562 /**
563 * An allocator for ElemEmpty instances.
564 */
565 XalanElemEmptyAllocator m_elemEmptyAllocator;
566
567 /**
568 * An allocator for ElemText instances.
569 */
570 XalanElemTextAllocator m_elemTextAllocator;
571
572 /**
573 * The stack of elements, pushed and popped as events occur.
574 */
575 ElemTemplateStackType m_elemStack;
576
577 /**
578 * Need to keep a stack of found whitespace elements so that
579 * whitespace elements next to non-whitespace elements can
580 * be merged. For instance: &lt;out> &lt;![CDATA[test]]> &lt;/out>
581 */
582 ElemTextLiteralStackType m_whiteSpaceElems;
583
584 /**
585 * The current template.
586 */
587 ElemTemplateElement* m_pTemplate;
588
589 class LastPoppedHolder
590 {
591 public:
592
593 LastPoppedHolder(StylesheetHandler& theStylesheetHandler) :
594 m_stylesheetHandler(theStylesheetHandler),
595 m_lastPopped(0)
596 {
597 }
598
599 ~LastPoppedHolder()
600 {
601 cleanup();
602 }
603
604 ElemTemplateElement*
605 operator->() const
606 {
607 return m_lastPopped;
608 }
609
610 bool
611 operator==(ElemTemplateElement* theRHS)
612 {
613 return m_lastPopped == theRHS;
614 }
615
616 bool
617 operator!=(ElemTemplateElement* theRHS)
618 {
619 return m_lastPopped != theRHS;
620 }
621
622 void
623 operator=(ElemTemplateElement* theRHS)
624 {
625 if (theRHS != m_lastPopped)
626 {
627 cleanup();
628
629 m_lastPopped = theRHS;
630 }
631 }
632
633 void
634 swap(LastPoppedHolder& theOther)
635 {
636 ElemTemplateElement* const theTemp = m_lastPopped;
637
638 m_lastPopped = theOther.m_lastPopped;
639
640 theOther.m_lastPopped = theTemp;
641 }
642
643 ElemTemplateElement*
644 get() const
645 {
646 return m_lastPopped;
647 }
648
649 private:
650
651 void
652 set(ElemTemplateElement* theNewElement)
653 {
654 if (theNewElement != m_lastPopped)
655 {
656 cleanup();
657
658 m_lastPopped = theNewElement;
659 }
660 }
661
662 // Not implemented...
663 LastPoppedHolder&
664 operator=(const LastPoppedHolder&);
665
666 LastPoppedHolder(const LastPoppedHolder&);
667
668 // Helper functions...
669 void
670 cleanup();
671
672 // Data members...
673 StylesheetHandler& m_stylesheetHandler;
674
675 ElemTemplateElement* m_lastPopped;
676 };
677
678 friend class LastPoppedHolder;
679
680 /**
681 * Manages the last element popped from the stack.
682 */
683 LastPoppedHolder m_lastPopped;
684
685 /**
686 * True if the process is in a template context.
687 */
688 bool m_inTemplate;
689
690 /**
691 * True if the stylesheet element was found, or if it was determined that
692 * the stylesheet is wrapperless.
693 */
694 bool m_foundStylesheet;
695
696 /**
697 * Flag to let us know when we've found an element inside the
698 * stylesheet that is not an xsl:import, so we can restrict imports
699 * to being the first elements.
700 */
701 bool m_foundNotImport;
702
703 XalanDOMString m_elementLocalName;
704
705 /**
706 * Accumulate character buffer to create contiguous character data
707 * where possible.
708 */
709 XalanDOMString m_accumulateText;
710
711 XalanDOMString m_includeBase;
712
713 BoolStackType m_inExtensionElementStack;
714
715 BoolStackType m_preserveSpaceStack;
716
717 // Note that these variables must not be saved by
718 // PushPopIncludeState...
719 unsigned long m_locatorsPushed;
720
721 QNameSetType m_globalVariableNames;
722
723 enum { eVariablesStackDefault = 20 };
724
725 QNameSetVectorType m_inScopeVariableNamesStack;
726
727 /**
728 * Init the wrapperless template
729 */
731 initWrapperless(
732 const XalanDOMChar* name,
733 const AttributeListType& atts,
734 const Locator* locator);
735
736 const XalanDOMString*
737 getNamespaceFromStack(const XalanDOMChar* theName,
739
740 const XalanDOMString*
741 getNamespaceForPrefixFromStack(const XalanDOMString& thePrefix) const;
742
743 class PushPopIncludeState;
744
745 friend class StylesheetHandler::PushPopIncludeState;
746
747 class PushPopIncludeState
748 {
749 public:
750
751 PushPopIncludeState(StylesheetHandler& theHandler);
752
753 ~PushPopIncludeState();
754
755 private:
756
757 StylesheetHandler& m_handler;
758
759 ElemTemplateStackType m_elemStack;
760
761 ElemTemplateElement* const m_pTemplate;
762
763 LastPoppedHolder m_lastPopped;
764
765 const bool m_inTemplate;
766
767 const bool m_foundStylesheet;
768
769 const XalanDOMString m_XSLNameSpaceURL;
770
771 const bool m_foundNotImport;
772
773 Stylesheet::NamespaceVectorType m_namespaceDecls;
774
776
777 NamespacesHandler m_namespacesHandler;
778
779 BoolStackType m_inExtensionElementStack;
780
781 BoolStackType m_preserveSpaceStack;
782 };
783
784 static const XalanDOMString s_emptyString;
785};
786
787
788
789}
790
791
792
793#endif // XALAN_STYLESHEETHANDLER_HEADER_GUARD
#define XALAN_XSLT_EXPORT
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
A SAX-based formatter interface for the XSL processor.
This class processes a stylesheet via SAX events, and inits the given stylesheet.
XalanSet< XalanQNameByReference > QNameSetType
virtual void cdata(const XMLCh *const ch, const size_type length)
Receive notification of cdata.
virtual void ignorableWhitespace(const XMLCh *const chars, const size_type length)
Receive notification of ignorable whitespace in element content.
void processInclude(const XalanDOMChar *name, const AttributeListType &atts, const Locator *locator)
Process xsl:include.
StylesheetHandler(Stylesheet &stylesheetTree, StylesheetConstructionContext &constructionContext)
Construct a StylesheetHandler ... it will add the DOM nodes to the document fragment.
virtual void endDocument()
Receive notification of the end of a document.
virtual void characters(const XMLCh *const chars, const size_type length)
Receive notification of character data.
XalanVector< bool > BoolStackType
virtual void resetDocument()
This method allows the user installed Document Handler to 'reset' itself, freeing all the memory reso...
XalanVector< ElemTemplateElement * > ElemTextLiteralStackType
virtual void entityReference(const XMLCh *const data)
Receive notification of a entityReference.
virtual void charactersRaw(const XMLCh *const chars, const size_type length)
Receive notification of character data.
virtual void startDocument()
Receive notification of the beginning of a document.
bool isAttrOK(const XalanDOMChar *attrName, const AttributeListType &atts, XalanSize_t which)
See if this is a xmlns attribute, and, if so, process it.
virtual void comment(const XMLCh *const data)
Called when a Comment is to be constructed.
virtual void startElement(const XMLCh *const name, AttributeListType &attrs)
Receive notification of the beginning of an element.
static void terminate()
Perform static shut down.
void processImport(const XalanDOMChar *name, const AttributeListType &atts, const Locator *locator)
Process xsl:import.
virtual void setDocumentLocator(const Locator *const locator)
Receive an object for locating the origin of SAX document events.
XalanVector< ElemTemplateElement * > ElemTemplateStackType
static void initialize(MemoryManager &theManager)
Perform static initialization.
bool processSpaceAttr(const XalanDOMChar *elementName, const XalanDOMChar *aname, const AttributeListType &atts, XalanSize_t which, const Locator *locator, bool &fPreserve)
Tell whether or not this is a xml:space attribute and, if so, process it.
XalanVector< QNameSetType, ConstructWithMemoryManagerTraits< QNameSetType > > QNameSetVectorType
virtual void endElement(const XMLCh *const name)
Receive notification of the end of an element.
bool processSpaceAttr(const XalanDOMChar *elementName, const AttributeListType &atts, const Locator *locator, bool &fPreserve)
Tell whether or not this is a xml:space attribute and, if so, process it.
virtual void processingInstruction(const XMLCh *const target, const XMLCh *const data)
Receive notification of a processing instruction.
This class represents the base stylesheet or an "import" stylesheet.
Xalan implementation of deque.
Class to represent a qualified name.
void swap(XalanVector< Type > &theLHS, XalanVector< Type > &theRHS)
size_t size_type
Definition XalanMap.hpp:46
xercesc::AttributeList AttributeListType
bool operator==(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
bool operator!=(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)