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 #include "ElemTemplateElement.hpp"
19
20
21
22 #include <cassert>
23
24
25
26 #include <xercesc/sax/AttributeList.hpp>
27
28
29
30 #include <xalanc/XalanDOM/XalanAttr.hpp>
31 #include <xalanc/XalanDOM/XalanDocument.hpp>
32 #include <xalanc/XalanDOM/XalanDOMException.hpp>
33
34
35
36 #include <xalanc/PlatformSupport/AttributeListImpl.hpp>
37 #include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp>
38 #include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
39 #include <xalanc/PlatformSupport/XalanUnicode.hpp>
40
41
42
43 #include <xalanc/DOMSupport/DOMServices.hpp>
44
45
46
47 #include <xalanc/XMLSupport/FormatterToText.hpp>
48
49
50
51 #include <xalanc/XPath/MutableNodeRefList.hpp>
52 #include <xalanc/XPath/XObjectFactory.hpp>
53 #include <xalanc/XPath/XPathExecutionContext.hpp>
54 #include <xalanc/XPath/XPath.hpp>
55
56
57
58 #include "Constants.hpp"
59 #include "ElemCallTemplate.hpp"
60 #include "ElemForEach.hpp"
61 #include "ElemTemplate.hpp"
62 #include "ElemTextLiteral.hpp"
63 #include "NamespacesHandler.hpp"
64 #include "NodeSorter.hpp"
65 #include "Stylesheet.hpp"
66 #include "StylesheetConstructionContext.hpp"
67 #include "StylesheetExecutionContext.hpp"
68 #include "StylesheetRoot.hpp"
69 #include "SelectionEvent.hpp"
70 #include "TracerEvent.hpp"
71
72
73
74 namespace XALAN_CPP_NAMESPACE {
75
76
77
78 const XalanDOMString ElemTemplateElement::s_emptyString(XalanMemMgrs::getDummyMemMgr());
79
80 const XalanQNameByReference ElemTemplateElement::s_emptyQName(s_emptyString, s_emptyString);
81
82
83
ElemTemplateElement(StylesheetConstructionContext & constructionContext,Stylesheet & stylesheetTree,XalanFileLoc lineNumber,XalanFileLoc columnNumber,int xslToken)84 ElemTemplateElement::ElemTemplateElement(
85 StylesheetConstructionContext& constructionContext,
86 Stylesheet& stylesheetTree,
87 XalanFileLoc lineNumber,
88 XalanFileLoc columnNumber,
89 int xslToken) :
90 PrefixResolver(),
91 m_stylesheet(stylesheetTree),
92 m_namespacesHandler(
93 constructionContext,
94 stylesheetTree.getNamespacesHandler(),
95 stylesheetTree.getNamespaces(),
96 stylesheetTree.getXSLTNamespaceURI()),
97 m_xslToken(xslToken),
98 m_parentNode(0),
99 m_nextSibling(0),
100 m_previousSibling(0),
101 m_firstChild(0),
102 m_locatorProxy(
103 lineNumber,
104 columnNumber,
105 constructionContext.getPooledString(stylesheetTree.getCurrentIncludeBaseIdentifier())),
106 m_flags(eCanGenerateAttributes)
107 {
108 }
109
110
111
ElemTemplateElement(StylesheetConstructionContext & constructionContext,Stylesheet & stylesheetTree,int xslToken,const XalanDOMString & baseURI,XalanFileLoc lineNumber,XalanFileLoc columnNumber)112 ElemTemplateElement::ElemTemplateElement(
113 StylesheetConstructionContext& constructionContext,
114 Stylesheet& stylesheetTree,
115 int xslToken,
116 const XalanDOMString& baseURI,
117 XalanFileLoc lineNumber,
118 XalanFileLoc columnNumber) :
119 PrefixResolver(),
120 m_stylesheet(stylesheetTree),
121 m_namespacesHandler(constructionContext.getMemoryManager()),
122 m_xslToken(xslToken),
123 m_parentNode(0),
124 m_nextSibling(0),
125 m_previousSibling(0),
126 m_firstChild(0),
127 m_locatorProxy(
128 lineNumber,
129 columnNumber,
130 constructionContext.getPooledString(baseURI)),
131 m_flags(eCanGenerateAttributes)
132 {
133 }
134
135
136
~ElemTemplateElement()137 ElemTemplateElement::~ElemTemplateElement()
138 {
139 }
140
141
142
143 const Locator*
getLocator() const144 ElemTemplateElement::getLocator() const
145 {
146 return &m_locatorProxy;
147 }
148
149
150
151 bool
isWhitespace() const152 ElemTemplateElement::isWhitespace() const
153 {
154 return false;
155 }
156
157
158
159 bool
isAttrOK(const XalanDOMChar * attrName,const AttributeListType & atts,XalanSize_t which,StylesheetConstructionContext & constructionContext) const160 ElemTemplateElement::isAttrOK(
161 const XalanDOMChar* attrName,
162 const AttributeListType& atts,
163 XalanSize_t which,
164 StylesheetConstructionContext& constructionContext) const
165 {
166 return m_stylesheet.isAttrOK(attrName, atts, which, constructionContext);
167 }
168
169
170
171 bool
processSpaceAttr(const XalanDOMChar * elementName,const XalanDOMChar * aname,const AttributeListType & atts,XalanSize_t which,StylesheetConstructionContext & constructionContext)172 ElemTemplateElement::processSpaceAttr(
173 const XalanDOMChar* elementName,
174 const XalanDOMChar* aname,
175 const AttributeListType& atts,
176 XalanSize_t which,
177 StylesheetConstructionContext& constructionContext)
178 {
179 if(constructionContext.isXMLSpaceAttribute(
180 aname,
181 getStylesheet(),
182 getLocator()) == false)
183 {
184 return false;
185 }
186 else
187 {
188 const XalanDOMChar* const spaceVal = atts.getValue(which);
189
190 if(equals(spaceVal, Constants::ATTRVAL_PRESERVE) == true)
191 {
192 m_flags |= eSpacePreserve;
193 }
194 else if (equals(spaceVal, Constants::ATTRVAL_DEFAULT) == false)
195 {
196 error(
197 constructionContext,
198 XalanMessages::ElementHasIllegalAttributeValue_3Param,
199 elementName,
200 aname,
201 spaceVal);
202 }
203
204 return true;
205 }
206 }
207
208
209
210 bool
isValidNCName(const XalanDOMString & s)211 ElemTemplateElement::isValidNCName(const XalanDOMString& s)
212 {
213 return XalanQName::isValidNCName(s);
214 }
215
216
217 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
218 const ElemTemplateElement*
startElement(StylesheetExecutionContext & executionContext) const219 ElemTemplateElement::startElement(StylesheetExecutionContext& executionContext) const
220 {
221 if(0 != executionContext.getTraceListeners())
222 {
223 executionContext.fireTraceEvent(
224 TracerEvent(executionContext, *this));
225 }
226 return 0;
227 }
228
229
230
231
232 void
endElement(StylesheetExecutionContext &) const233 ElemTemplateElement::endElement(StylesheetExecutionContext& /*executionContext*/) const
234 {
235 }
236
237
238
239 void
execute(StylesheetExecutionContext & executionContext) const240 ElemTemplateElement::execute(StylesheetExecutionContext& executionContext) const
241 {
242 const ElemTemplateElement* const invoker =
243 getParentNodeElem();
244
245 const ElemTemplateElement* currentElement = this;
246
247 const ElemTemplateElement* nextElement = 0;
248
249 executionContext.pushInvoker(invoker);
250
251 while (currentElement != 0)
252 {
253 nextElement = currentElement->startElement(executionContext);
254
255 while (0 == nextElement)
256 {
257 currentElement->endElement(executionContext);
258
259 if (currentElement->getInvoker(executionContext) == invoker)
260 {
261 nextElement = 0;
262
263 break;
264 }
265
266 const ElemTemplateElement* const localInvoker =
267 currentElement->getInvoker(executionContext);
268 assert(localInvoker != 0);
269
270 nextElement =
271 localInvoker->getNextChildElemToExecute(
272 executionContext,
273 currentElement);
274
275 if (0 == nextElement)
276 {
277 currentElement = currentElement->getInvoker(executionContext);
278 }
279 }
280
281 currentElement = nextElement;
282 }
283
284 executionContext.popInvoker();
285 }
286
287
288
289 void
executeChildren(StylesheetExecutionContext & executionContext) const290 ElemTemplateElement::executeChildren(StylesheetExecutionContext& executionContext) const
291 {
292 const ElemTemplateElement* element = beginExecuteChildren(executionContext);
293
294 while (element != 0)
295 {
296 element->execute(executionContext);
297
298 element = getNextChildElemToExecute(executionContext,element);
299 }
300
301 endExecuteChildren(executionContext);
302 }
303
304
305
306 const ElemTemplateElement*
beginExecuteChildren(StylesheetExecutionContext & executionContext) const307 ElemTemplateElement::beginExecuteChildren(StylesheetExecutionContext& executionContext) const
308 {
309 if (hasParams() == true || hasVariables() == true)
310 {
311 assert(hasDirectTemplate() == false);
312
313 executionContext.pushElementFrame(this);
314 }
315
316 return getFirstChildElemToExecute(executionContext);
317 }
318
319
320
321 void
endExecuteChildren(StylesheetExecutionContext & executionContext) const322 ElemTemplateElement::endExecuteChildren(StylesheetExecutionContext& executionContext) const
323 {
324 if (hasParams() == true || hasVariables() == true)
325 {
326 executionContext.popElementFrame();
327 }
328 else if (hasDirectTemplate() == true)
329 {
330 executionContext.popInvoker();
331 executionContext.popContextMarker();
332 }
333 }
334
335
336
337 const ElemTemplateElement*
beginChildrenToString(StylesheetExecutionContext & executionContext,XalanDOMString & result) const338 ElemTemplateElement::beginChildrenToString(
339 StylesheetExecutionContext& executionContext,
340 XalanDOMString& result) const
341 {
342 if (hasSingleTextChild() == true)
343 {
344 assert(m_textLiteralChild != 0);
345
346 result.assign(m_textLiteralChild->getText(), m_textLiteralChild->getLength());
347
348 return 0;
349 }
350 else
351 {
352 result.reserve(result.length() + 1024);
353
354 executionContext.beginFormatToText(result);
355
356 return beginExecuteChildren(executionContext);
357 }
358 }
359
360
361
362 void
endChildrenToString(StylesheetExecutionContext & executionContext) const363 ElemTemplateElement::endChildrenToString(
364 StylesheetExecutionContext& executionContext) const
365 {
366 if (hasSingleTextChild() == false)
367 {
368 endExecuteChildren(executionContext);
369
370 executionContext.endFormatToText();
371 }
372 }
373
374
375
376 const ElemTemplateElement*
getInvoker(StylesheetExecutionContext &) const377 ElemTemplateElement::getInvoker(StylesheetExecutionContext& /*executionContext*/) const
378 {
379 return getParentNodeElem();
380 }
381 #endif
382
383
384
385 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
386 void
execute(StylesheetExecutionContext & executionContext) const387 ElemTemplateElement::execute(StylesheetExecutionContext& executionContext) const
388 {
389 if(0 != executionContext.getTraceListeners())
390 {
391 executionContext.fireTraceEvent(
392 TracerEvent(executionContext, *this));
393 }
394 }
395
396
397
398 void
executeChildren(StylesheetExecutionContext & executionContext) const399 ElemTemplateElement::executeChildren(StylesheetExecutionContext& executionContext) const
400 {
401 if (hasChildren() == true)
402 {
403 if (hasDirectTemplate() == true)
404 {
405 assert(m_directTemplate != 0);
406
407 // This is temporary, until we can process stylesheet in such a way that we
408 // can detect variable references...
409 const StylesheetExecutionContext::PushAndPopContextMarker thePushAndPop(executionContext);
410
411 m_directTemplate->execute(executionContext);
412 }
413 else
414 {
415 if (hasParams() == true || hasVariables() == true)
416 {
417 const StylesheetExecutionContext::PushAndPopElementFrame thePushAndPop(executionContext, this);
418
419 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
420 {
421 node->execute(executionContext);
422 }
423 }
424 else
425 {
426 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
427 {
428 node->execute(executionContext);
429 }
430 }
431 }
432 }
433 }
434
435
436
437 void
executeChildren(StylesheetExecutionContext & executionContext,XalanNode * sourceNode) const438 ElemTemplateElement::executeChildren(
439 StylesheetExecutionContext& executionContext,
440 XalanNode* sourceNode) const
441 {
442 if (hasChildren() == true)
443 {
444 XalanNode* const theCurrentNode = executionContext.getCurrentNode();
445
446 if (theCurrentNode == sourceNode)
447 {
448 executeChildren(executionContext);
449 }
450 else
451 {
452 const XPathExecutionContext::CurrentNodePushAndPop theCurrentNodePushAndPop(executionContext, sourceNode);
453
454 executeChildren(executionContext);
455 }
456 }
457 }
458
459
460
461 XalanDOMString&
doChildrenToString(StylesheetExecutionContext & executionContext,XalanDOMString & result) const462 ElemTemplateElement::doChildrenToString(
463 StylesheetExecutionContext& executionContext,
464 XalanDOMString& result) const
465 {
466 reserve(result, length(result) + 1024);
467
468 // Create a print writer and formatter to generate the children as
469 // a string.
470 DOMStringPrintWriter thePrintWriter(result);
471
472 // Borrow a FormatterToText, and don't normalize CR/LF, since we don't want
473 // this text to be normalized. Finally, have the formatter handle any ignorable
474 // whitespace events.
475 StylesheetExecutionContext::BorrowReturnFormatterToText theFormatter(
476 executionContext,
477 thePrintWriter,
478 false,
479 true);
480
481 // Create an object to set and restore the execution state.
482 StylesheetExecutionContext::OutputContextPushPop theOutputContextPushPop(
483 executionContext,
484 theFormatter.get());
485
486 theFormatter->startDocument();
487
488 executeChildren(executionContext);
489
490 theFormatter->endDocument();
491
492 return result;
493 }
494
495
496
497 const XalanDOMString&
childrenToString(StylesheetExecutionContext & executionContext,XalanDOMString & result) const498 ElemTemplateElement::childrenToString(
499 StylesheetExecutionContext& executionContext,
500 XalanDOMString& result) const
501 {
502 if (hasSingleTextChild() == true)
503 {
504 assert(m_textLiteralChild != 0);
505
506 assign(result, m_textLiteralChild->getText(), m_textLiteralChild->getLength());
507 }
508 else
509 {
510 doChildrenToString(executionContext, result);
511 }
512
513 return result;
514 }
515
516
517
518 void
childrenToResultAttribute(StylesheetExecutionContext & executionContext,const XalanDOMString & theName) const519 ElemTemplateElement::childrenToResultAttribute(
520 StylesheetExecutionContext& executionContext,
521 const XalanDOMString& theName) const
522 {
523 if (hasSingleTextChild() == true)
524 {
525 executionContext.addResultAttribute(
526 theName,
527 m_textLiteralChild->getText());
528 }
529 else
530 {
531 const StylesheetExecutionContext::GetCachedString theResult(executionContext);
532
533 childrenToString(executionContext, theResult.get());
534
535 executionContext.addResultAttribute(
536 theName,
537 theResult.get());
538 }
539 }
540
541
542
543 void
childrenToResultComment(StylesheetExecutionContext & executionContext) const544 ElemTemplateElement::childrenToResultComment(StylesheetExecutionContext& executionContext) const
545 {
546 const StylesheetExecutionContext::GetCachedString theGuard(executionContext);
547
548 XalanDOMString& theData = theGuard.get();
549
550 childrenToString(executionContext, theData);
551
552 XalanDOMString::iterator theEnd =
553 theData.end();
554
555 XalanDOMString::iterator theCurrent =
556 theData.begin();
557
558 // We need to fix up any occurrences of the sequence '--' in
559 // the comment's data by inserting a space between them. Also,
560 // if the data ends with a '-', then we must append a space to
561 // the data.
562 while(theCurrent != theEnd)
563 {
564 const XalanDOMChar theChar = *theCurrent;
565
566 if (theChar == XalanUnicode::charHyphenMinus)
567 {
568 XalanDOMString::iterator theNext =
569 theCurrent + 1;
570
571 if (theNext == theEnd ||
572 *theNext == XalanUnicode::charHyphenMinus)
573 {
574 theCurrent =
575 theData.insert(
576 theNext,
577 XalanUnicode::charSpace);
578
579 theEnd = theData.end();
580 }
581 }
582
583 ++theCurrent;
584 }
585
586 executionContext.comment(theData.c_str());
587 }
588
589
590
591 void
childrenToResultPI(StylesheetExecutionContext & executionContext,const XalanDOMString & theTarget) const592 ElemTemplateElement::childrenToResultPI(
593 StylesheetExecutionContext& executionContext,
594 const XalanDOMString& theTarget) const
595 {
596 const StylesheetExecutionContext::GetCachedString theGuard(executionContext);
597
598 XalanDOMString& theData = theGuard.get();
599
600 childrenToString(executionContext, theData);
601
602 XalanDOMString::iterator theEnd =
603 theData.end();
604
605 XalanDOMString::iterator theCurrent =
606 theData.begin();
607
608 // We need to fix up any occurrences of the sequence '?>' in
609 // the PI's data by inserting a space between them.
610 while(theCurrent != theEnd)
611 {
612 const XalanDOMChar theChar = *theCurrent;
613
614 if (theChar == XalanUnicode::charQuestionMark)
615 {
616 XalanDOMString::iterator theNext =
617 theCurrent + 1;
618
619 if (theNext != theEnd &&
620 *theNext == XalanUnicode::charGreaterThanSign)
621 {
622 theCurrent =
623 theData.insert(
624 theNext,
625 XalanUnicode::charSpace);
626
627 theEnd = theData.end();
628
629 // Move forward, since we're not interested in
630 // the '>' character.
631 ++theCurrent;
632 }
633 }
634
635 ++theCurrent;
636 }
637
638 executionContext.processingInstruction(
639 theTarget.c_str(),
640 theData.c_str());
641 }
642 #endif
643
644
645
646
647 typedef StylesheetExecutionContext::GetCachedString ECGetCachedString;
648 typedef StylesheetConstructionContext::GetCachedString CCGetCachedString;
649
650
651
652 void
error(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode) const653 ElemTemplateElement::error(
654 StylesheetExecutionContext& theContext,
655 XalanMessages::Codes theCode) const
656 {
657 const ECGetCachedString theGuard(theContext);
658
659 theContext.problem(
660 StylesheetExecutionContext::eXSLTProcessor,
661 StylesheetExecutionContext::eError,
662 XalanMessageLoader::getMessage(
663 theGuard.get(),
664 theCode),
665 getLocator(),
666 theContext.getCurrentNode());
667 }
668
669
670
671 void
error(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken) const672 ElemTemplateElement::error(
673 StylesheetExecutionContext& theContext,
674 XalanMessages::Codes theCode,
675 const XalanDOMString& theToken) const
676 {
677 const ECGetCachedString theGuard(theContext);
678
679 theContext.problem(
680 StylesheetExecutionContext::eXSLTProcessor,
681 StylesheetExecutionContext::eError,
682 XalanMessageLoader::getMessage(
683 theGuard.get(),
684 theCode,
685 theToken),
686 getLocator(),
687 theContext.getCurrentNode());
688 }
689
690
691
692 void
error(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const Locator * theLocator) const693 ElemTemplateElement::error(
694 StylesheetExecutionContext& theContext,
695 XalanMessages::Codes theCode,
696 const Locator* theLocator) const
697 {
698 const ECGetCachedString theGuard(theContext);
699
700 theContext.problem(
701 StylesheetExecutionContext::eXSLTProcessor,
702 StylesheetExecutionContext::eError,
703 XalanMessageLoader::getMessage(
704 theGuard.get(),
705 theCode),
706 theLocator,
707 theContext.getCurrentNode());
708 }
709
710
711
712 void
warn(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode) const713 ElemTemplateElement::warn(
714 StylesheetExecutionContext& theContext,
715 XalanMessages::Codes theCode) const
716 {
717 const ECGetCachedString theGuard(theContext);
718
719 theContext.problem(
720 StylesheetExecutionContext::eXSLTProcessor,
721 StylesheetExecutionContext::eWarning,
722 XalanMessageLoader::getMessage(
723 theGuard.get(),
724 theCode),
725 getLocator(),
726 theContext.getCurrentNode());
727 }
728
729
730
731 void
warn(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const Locator * theLocator) const732 ElemTemplateElement::warn(
733 StylesheetExecutionContext& theContext,
734 XalanMessages::Codes theCode,
735 const Locator* theLocator) const
736 {
737 const ECGetCachedString theGuard(theContext);
738
739 theContext.problem(
740 StylesheetExecutionContext::eXSLTProcessor,
741 StylesheetExecutionContext::eWarning,
742 XalanMessageLoader::getMessage(
743 theGuard.get(),
744 theCode),
745 theLocator,
746 theContext.getCurrentNode());
747 }
748
749
750
751 void
warn(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken) const752 ElemTemplateElement::warn(
753 StylesheetExecutionContext& theContext,
754 XalanMessages::Codes theCode,
755 const XalanDOMString& theToken) const
756 {
757 const ECGetCachedString theGuard(theContext);
758
759 theContext.problem(
760 StylesheetExecutionContext::eXSLTProcessor,
761 StylesheetExecutionContext::eWarning,
762 XalanMessageLoader::getMessage(
763 theGuard.get(),
764 theCode,
765 theToken),
766 getLocator(),
767 theContext.getCurrentNode());
768 }
769
770
771
772 void
warn(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMChar * theToken1,const XalanDOMChar * theToken2,const XalanDOMChar * theToken3)773 ElemTemplateElement::warn(
774 StylesheetConstructionContext& theContext,
775 XalanMessages::Codes theCode,
776 const XalanDOMChar* theToken1,
777 const XalanDOMChar* theToken2,
778 const XalanDOMChar* theToken3)
779 {
780 const CCGetCachedString theGuard(theContext);
781
782 theContext.problem(
783 StylesheetConstructionContext::eXSLTProcessor,
784 StylesheetConstructionContext::eWarning,
785 XalanMessageLoader::getMessage(
786 theGuard.get(),
787 theCode,
788 theToken1,
789 theToken2,
790 theToken3),
791 getLocator(),
792 0);
793 }
794
795
796
797 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode)798 ElemTemplateElement::error(
799 StylesheetConstructionContext& theContext,
800 XalanMessages::Codes theCode)
801 {
802 const CCGetCachedString theGuard(theContext);
803
804 theContext.problem(
805 StylesheetConstructionContext::eXSLTProcessor,
806 StylesheetConstructionContext::eError,
807 XalanMessageLoader::getMessage(
808 theGuard.get(),
809 theCode),
810 getLocator(),
811 0);
812 }
813
814
815
816 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken,const Locator * theLocator)817 ElemTemplateElement::error(
818 StylesheetConstructionContext& theContext,
819 XalanMessages::Codes theCode,
820 const XalanDOMString& theToken,
821 const Locator* theLocator)
822 {
823 const CCGetCachedString theGuard(theContext);
824
825 theContext.problem(
826 StylesheetConstructionContext::eXSLTProcessor,
827 StylesheetConstructionContext::eError,
828 XalanMessageLoader::getMessage(
829 theGuard.get(),
830 theCode,
831 theToken),
832 theLocator,
833 0);
834 }
835
836
837
838 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken)839 ElemTemplateElement::error(
840 StylesheetConstructionContext& theContext,
841 XalanMessages::Codes theCode,
842 const XalanDOMString& theToken)
843 {
844 const CCGetCachedString theGuard(theContext);
845
846 theContext.problem(
847 StylesheetConstructionContext::eXSLTProcessor,
848 StylesheetConstructionContext::eError,
849 XalanMessageLoader::getMessage(
850 theGuard.get(),
851 theCode,
852 theToken),
853 getLocator(),
854 0);
855 }
856
857
858
859 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken1,const XalanDOMString & theToken2)860 ElemTemplateElement::error(
861 StylesheetConstructionContext& theContext,
862 XalanMessages::Codes theCode,
863 const XalanDOMString& theToken1,
864 const XalanDOMString& theToken2)
865 {
866 const CCGetCachedString theGuard(theContext);
867
868 theContext.problem(
869 StylesheetConstructionContext::eXSLTProcessor,
870 StylesheetConstructionContext::eError,
871 XalanMessageLoader::getMessage(
872 theGuard.get(),
873 theCode,
874 theToken1,
875 theToken2),
876 getLocator(),
877 0);
878 }
879
880
881
882 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMChar * theToken1,const XalanDOMChar * theToken2)883 ElemTemplateElement::error(
884 StylesheetConstructionContext& theContext,
885 XalanMessages::Codes theCode,
886 const XalanDOMChar* theToken1,
887 const XalanDOMChar* theToken2)
888 {
889 const CCGetCachedString theGuard(theContext);
890
891 theContext.problem(
892 StylesheetConstructionContext::eXSLTProcessor,
893 StylesheetConstructionContext::eError,
894 XalanMessageLoader::getMessage(
895 theGuard.get(),
896 theCode,
897 theToken1,
898 theToken2),
899 getLocator(),
900 0);
901 }
902
903
904
905 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMChar * theToken1,const XalanDOMChar * theToken2,const XalanDOMChar * theToken3)906 ElemTemplateElement::error(
907 StylesheetConstructionContext& theContext,
908 XalanMessages::Codes theCode,
909 const XalanDOMChar* theToken1,
910 const XalanDOMChar* theToken2,
911 const XalanDOMChar* theToken3)
912 {
913 const CCGetCachedString theGuard(theContext);
914
915 theContext.problem(
916 StylesheetConstructionContext::eXSLTProcessor,
917 StylesheetConstructionContext::eError,
918 XalanMessageLoader::getMessage(
919 theGuard.get(),
920 theCode,
921 theToken1,
922 theToken2,
923 theToken3),
924 getLocator(),
925 0);
926 }
927
928
929
930 const XalanQName&
getNameAttribute() const931 ElemTemplateElement::getNameAttribute() const
932 {
933 return s_emptyQName;
934 }
935
936
937
938 void
addToStylesheet(StylesheetConstructionContext &,Stylesheet &)939 ElemTemplateElement::addToStylesheet(
940 StylesheetConstructionContext& /* constructionContext */,
941 Stylesheet& /* theStylesheet */)
942 {
943 // An illegal call to addToStylesheet() was made during compilation of the stylesheet.
944 assert ( false );
945 }
946
947
948
949 void
processSortElement(StylesheetConstructionContext & constructionContext,Stylesheet &,const AttributeListType &,const Locator * locator)950 ElemTemplateElement::processSortElement(
951 StylesheetConstructionContext& constructionContext,
952 Stylesheet& /* theStylesheet */,
953 const AttributeListType& /* atts */,
954 const Locator* locator)
955 {
956 error(
957 constructionContext,
958 XalanMessages::ElementIsNotAllowedAtThisPosition_1Param,
959 Constants::ELEMNAME_SORT_WITH_PREFIX_STRING,
960 locator);
961 }
962
963
964
965 void
setDefaultTemplate(bool value)966 ElemTemplateElement::setDefaultTemplate(bool value)
967 {
968 m_flags |= eDefaultTemplate;
969
970 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
971 {
972 node->setDefaultTemplate(value);
973 }
974 }
975
976
977
978 ElemTemplateElement*
getFirstChildElem() const979 ElemTemplateElement::getFirstChildElem() const
980 {
981 return m_firstChild;
982 }
983
984
985
986 void
setFirstChildElem(ElemTemplateElement * theElement)987 ElemTemplateElement::setFirstChildElem(ElemTemplateElement* theElement)
988 {
989 m_firstChild = theElement;
990 }
991
992
993
994 ElemTemplateElement*
getLastChildElem() const995 ElemTemplateElement::getLastChildElem() const
996 {
997 ElemTemplateElement* lastChild = 0;
998
999 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
1000 {
1001 lastChild = node;
1002 }
1003
1004 return lastChild;
1005 }
1006
1007
1008
1009 ElemTemplateElement*
getNextSiblingElem() const1010 ElemTemplateElement::getNextSiblingElem() const
1011 {
1012 return m_nextSibling;
1013 }
1014
1015
1016
1017 void
setNextSiblingElem(ElemTemplateElement * theSibling)1018 ElemTemplateElement::setNextSiblingElem(ElemTemplateElement* theSibling)
1019 {
1020 m_nextSibling = theSibling;
1021 }
1022
1023
1024
1025 ElemTemplateElement*
getPreviousSiblingElem() const1026 ElemTemplateElement::getPreviousSiblingElem() const
1027 {
1028 return m_previousSibling;
1029 }
1030
1031
1032
1033 void
setPreviousSiblingElem(ElemTemplateElement * theSibling)1034 ElemTemplateElement::setPreviousSiblingElem(ElemTemplateElement* theSibling)
1035 {
1036 m_previousSibling = theSibling;
1037 }
1038
1039
1040
1041 ElemTemplateElement*
getParentNodeElem() const1042 ElemTemplateElement::getParentNodeElem() const
1043 {
1044 return m_parentNode;
1045 }
1046
1047
1048
1049 void
setParentNodeElem(ElemTemplateElement * theParent)1050 ElemTemplateElement::setParentNodeElem(ElemTemplateElement* theParent)
1051 {
1052 m_parentNode = theParent;
1053 }
1054
1055
1056
1057 ElemTemplateElement*
appendChildElem(ElemTemplateElement * newChild)1058 ElemTemplateElement::appendChildElem(ElemTemplateElement* newChild)
1059 {
1060 assert(newChild != 0);
1061 assert(newChild->getXSLToken() != StylesheetConstructionContext::ELEMNAME_TEXT);
1062 assert(newChild->getXSLToken() != StylesheetConstructionContext::ELEMNAME_UNDEFINED);
1063
1064 if (childTypeAllowed(newChild->getXSLToken()) == false)
1065 {
1066 throw XalanDOMException(XalanDOMException::HIERARCHY_REQUEST_ERR);
1067 }
1068 else if(0 == m_firstChild)
1069 {
1070 m_firstChild = newChild;
1071
1072 newChild->setPreviousSiblingElem(0);
1073 }
1074 else
1075 {
1076 ElemTemplateElement* const last = getLastChildElem();
1077 assert(last != 0);
1078
1079 last->setNextSiblingElem(newChild);
1080
1081 newChild->setPreviousSiblingElem(last);
1082 }
1083
1084 newChild->setParentNodeElem(this);
1085 newChild->setNextSiblingElem(0);
1086
1087 return newChild;
1088 }
1089
1090
1091
1092 const XPath*
getXPath(XalanSize_t) const1093 ElemTemplateElement::getXPath(XalanSize_t /* index */) const
1094 {
1095 return 0;
1096 }
1097
1098
1099
1100 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1101 const ElemTemplateElement*
findTemplateToTransformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child) const1102 ElemTemplateElement::findTemplateToTransformChild(
1103 StylesheetExecutionContext& executionContext,
1104 const ElemTemplateElement& xslInstruction,
1105 const ElemTemplateElement* theTemplate,
1106 XalanNode* child) const
1107 {
1108 assert(child != 0);
1109
1110 return findTemplateToTransformChild(
1111 executionContext,
1112 xslInstruction,
1113 theTemplate,
1114 child,
1115 child->getNodeType());
1116 }
1117
1118
1119 const ElemTemplateElement*
findTemplateToTransformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child,XalanNode::NodeType nodeType) const1120 ElemTemplateElement::findTemplateToTransformChild(
1121 StylesheetExecutionContext& executionContext,
1122 const ElemTemplateElement& xslInstruction,
1123 const ElemTemplateElement* theTemplate,
1124 XalanNode* child,
1125 XalanNode::NodeType nodeType) const
1126 {
1127 assert(child != 0);
1128
1129 if(0 == theTemplate)
1130 {
1131 // Find the XSL template that is the best match for the
1132 // element...
1133 const bool isApplyImports = xslInstruction.getXSLToken() ==
1134 StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS;
1135 assert(isApplyImports == false || executionContext.getCurrentTemplate() != 0);
1136
1137 const Stylesheet* stylesheetTree = isApplyImports == true ?
1138 &executionContext.getCurrentTemplate()->getStylesheet() :
1139 &getStylesheet().getStylesheetRoot();
1140
1141 theTemplate = stylesheetTree->findTemplate(
1142 executionContext,
1143 child,
1144 nodeType,
1145 *executionContext.getCurrentMode(),
1146 isApplyImports);
1147 }
1148
1149 if(0 == theTemplate)
1150 {
1151 switch(nodeType)
1152 {
1153 case XalanNode::DOCUMENT_FRAGMENT_NODE:
1154 case XalanNode::ELEMENT_NODE:
1155 theTemplate = getStylesheet().getStylesheetRoot().getDefaultRule();
1156 break;
1157
1158 case XalanNode::CDATA_SECTION_NODE:
1159 case XalanNode::TEXT_NODE:
1160 theTemplate = getStylesheet().getStylesheetRoot().getDefaultTextRule();
1161 break;
1162
1163 case XalanNode::ATTRIBUTE_NODE:
1164 if (DOMServices::isNamespaceDeclaration(static_cast<const XalanAttr&>(*child)) == false)
1165 {
1166 theTemplate = getStylesheet().getStylesheetRoot().getDefaultTextRule();
1167 }
1168 break;
1169
1170 case XalanNode::DOCUMENT_NODE:
1171 theTemplate = getStylesheet().getStylesheetRoot().getDefaultRootRule();
1172 break;
1173
1174 default:
1175 break;
1176 }
1177 }
1178
1179 if(0 != theTemplate)
1180 {
1181 if(theTemplate == getStylesheet().getStylesheetRoot().getDefaultTextRule())
1182 {
1183 switch(nodeType)
1184 {
1185 case XalanNode::CDATA_SECTION_NODE:
1186 case XalanNode::TEXT_NODE:
1187 executionContext.cloneToResultTree(
1188 *child,
1189 XalanNode::TEXT_NODE,
1190 true,
1191 false,
1192 getLocator());
1193 break;
1194
1195 case XalanNode::ATTRIBUTE_NODE:
1196 {
1197 const XalanDOMString& val = child->getNodeValue();
1198
1199 const XalanDOMString::size_type len = val.length();
1200
1201 if (len > 0)
1202 {
1203 executionContext.characters(
1204 val.c_str(),
1205 0,
1206 len);
1207 }
1208 }
1209 break;
1210
1211 default:
1212 assert(false);
1213 break;
1214 }
1215 }
1216 else
1217 {
1218 if(0 != executionContext.getTraceListeners())
1219 {
1220 const TracerEvent te(executionContext,
1221 *theTemplate);
1222
1223 executionContext.fireTraceEvent(te);
1224 }
1225
1226 return theTemplate;
1227 }
1228 }
1229 return 0;
1230 }
1231
1232
1233
1234 #else
1235 void
transformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child) const1236 ElemTemplateElement::transformChild(
1237 StylesheetExecutionContext& executionContext,
1238 const ElemTemplateElement& xslInstruction,
1239 const ElemTemplateElement* theTemplate,
1240 XalanNode* child) const
1241 {
1242 assert(child != 0);
1243
1244 transformChild(
1245 executionContext,
1246 xslInstruction,
1247 theTemplate,
1248 child,
1249 child->getNodeType());
1250 }
1251
1252
1253
1254
1255 void
transformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child,XalanNode::NodeType nodeType) const1256 ElemTemplateElement::transformChild(
1257 StylesheetExecutionContext& executionContext,
1258 const ElemTemplateElement& xslInstruction,
1259 const ElemTemplateElement* theTemplate,
1260 XalanNode* child,
1261 XalanNode::NodeType nodeType) const
1262 {
1263 assert(child != 0);
1264
1265 if(0 == theTemplate)
1266 {
1267 // Find the XSL template that is the best match for the
1268 // element...
1269 const bool isApplyImports = xslInstruction.getXSLToken() ==
1270 StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS;
1271 assert(isApplyImports == false || executionContext.getCurrentTemplate() != 0);
1272
1273 const Stylesheet* stylesheetTree = isApplyImports == true ?
1274 &executionContext.getCurrentTemplate()->getStylesheet() :
1275 &getStylesheet().getStylesheetRoot();
1276
1277 theTemplate = stylesheetTree->findTemplate(
1278 executionContext,
1279 child,
1280 nodeType,
1281 *executionContext.getCurrentMode(),
1282 isApplyImports);
1283 }
1284
1285 if(0 == theTemplate)
1286 {
1287 switch(nodeType)
1288 {
1289 case XalanNode::DOCUMENT_FRAGMENT_NODE:
1290 case XalanNode::ELEMENT_NODE:
1291 theTemplate = getStylesheet().getStylesheetRoot().getDefaultRule();
1292 break;
1293
1294 case XalanNode::CDATA_SECTION_NODE:
1295 case XalanNode::TEXT_NODE:
1296 case XalanNode::ATTRIBUTE_NODE:
1297 theTemplate = getStylesheet().getStylesheetRoot().getDefaultTextRule();
1298 break;
1299
1300 case XalanNode::DOCUMENT_NODE:
1301 theTemplate = getStylesheet().getStylesheetRoot().getDefaultRootRule();
1302 break;
1303
1304 default:
1305 break;
1306 }
1307 }
1308
1309 if(0 != theTemplate)
1310 {
1311 if(theTemplate == getStylesheet().getStylesheetRoot().getDefaultTextRule())
1312 {
1313 switch(nodeType)
1314 {
1315 case XalanNode::CDATA_SECTION_NODE:
1316 case XalanNode::TEXT_NODE:
1317 executionContext.cloneToResultTree(
1318 *child,
1319 XalanNode::TEXT_NODE,
1320 true,
1321 false,
1322 getLocator());
1323 break;
1324
1325 case XalanNode::ATTRIBUTE_NODE:
1326 {
1327 const XalanDOMString& val = child->getNodeValue();
1328
1329 const XalanDOMString::size_type len = length(val);
1330
1331 if (len > 0)
1332 {
1333 executionContext.characters(
1334 val.c_str(),
1335 0,
1336 len);
1337 }
1338 }
1339 break;
1340
1341 default:
1342 assert(false);
1343 break;
1344 }
1345 }
1346 else
1347 {
1348 if(0 != executionContext.getTraceListeners())
1349 {
1350 const TracerEvent te(executionContext,
1351 *theTemplate);
1352
1353 executionContext.fireTraceEvent(te);
1354 }
1355
1356 theTemplate->executeChildren(executionContext, child);
1357 }
1358 }
1359 }
1360 #endif
1361
1362
1363
1364 void
postConstruction(StylesheetConstructionContext & constructionContext,const NamespacesHandler & theParentHandler)1365 ElemTemplateElement::postConstruction(
1366 StylesheetConstructionContext& constructionContext,
1367 const NamespacesHandler& theParentHandler)
1368 {
1369 namespacesPostConstruction(
1370 constructionContext,
1371 theParentHandler,
1372 m_namespacesHandler);
1373
1374 if (hasChildren() == true)
1375 {
1376 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
1377 {
1378 node->postConstruction(constructionContext, m_namespacesHandler);
1379
1380 const int theToken = node->getXSLToken();
1381
1382 if (hasVariables() == false &&
1383 (theToken == StylesheetConstructionContext::ELEMNAME_VARIABLE ||
1384 theToken == StylesheetConstructionContext::ELEMNAME_PARAM))
1385 {
1386 m_flags |= eHasVariables;
1387 }
1388
1389 if (hasParams() == false &&
1390 theToken == StylesheetConstructionContext::ELEMNAME_WITH_PARAM)
1391 {
1392 m_flags |= eHasParams;
1393 }
1394 }
1395
1396 assert(m_firstChild != 0);
1397
1398 const int theToken = m_firstChild->getXSLToken();
1399
1400 // There are opportunities for optimization if there's only one
1401 // xsl:text child node. See childrenToString()...
1402 if (theToken == StylesheetConstructionContext::ELEMNAME_TEXT_LITERAL_RESULT &&
1403 m_firstChild->getNextSiblingElem() == 0)
1404 {
1405 m_flags |= eHasSingleTextChild;
1406 }
1407 else if (theToken == StylesheetConstructionContext::ELEMNAME_CALL_TEMPLATE &&
1408 m_firstChild->getNextSiblingElem() == 0)
1409 {
1410 // Just a single xsl:call-template child, so we don't need to
1411 // execute it if it has no params -- we can just execute the
1412 // template directly...
1413 if (m_firstChild->hasParams() == false)
1414 {
1415 m_flags |= eHasDirectTemplate;
1416
1417 ElemCallTemplate* const theCallTemplateChild =
1418 static_cast<ElemCallTemplate*>(m_firstChild);
1419
1420 m_directTemplate = theCallTemplateChild->getTemplate();
1421 }
1422 }
1423 else if (canGenerateAttributes() == false &&
1424 theToken != StylesheetConstructionContext::ELEMNAME_LITERAL_RESULT)
1425 {
1426 m_flags |= eCanGenerateAttributes;
1427 }
1428 }
1429 }
1430
1431
1432
1433 void
namespacesPostConstruction(StylesheetConstructionContext & constructionContext,const NamespacesHandler & theParentHandler,NamespacesHandler & theHandler)1434 ElemTemplateElement::namespacesPostConstruction(
1435 StylesheetConstructionContext& constructionContext,
1436 const NamespacesHandler& theParentHandler,
1437 NamespacesHandler& theHandler)
1438 {
1439 theHandler.postConstruction(
1440 constructionContext,
1441 true,
1442 getElementName(),
1443 &theParentHandler);
1444 }
1445
1446
1447
1448 const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString & prefix) const1449 ElemTemplateElement::getNamespaceForPrefix(const XalanDOMString& prefix) const
1450 {
1451 return getNamespaceForPrefixInternal(prefix);
1452 }
1453
1454
1455
1456 bool
processPrefixControl(StylesheetConstructionContext & constructionContext,const Stylesheet & stylesheetTree,const XalanDOMString & localName,const XalanDOMChar * attrValue)1457 ElemTemplateElement::processPrefixControl(
1458 StylesheetConstructionContext& constructionContext,
1459 const Stylesheet& stylesheetTree,
1460 const XalanDOMString& localName,
1461 const XalanDOMChar* attrValue)
1462 {
1463 if(equals(localName, Constants::ATTRNAME_EXTENSIONELEMENTPREFIXES))
1464 {
1465 m_namespacesHandler.processExtensionElementPrefixes(
1466 constructionContext,
1467 attrValue,
1468 stylesheetTree.getNamespaces());
1469
1470 return true;
1471 }
1472 else if (equals(localName, Constants::ATTRNAME_EXCLUDE_RESULT_PREFIXES))
1473 {
1474 m_namespacesHandler.processExcludeResultPrefixes(
1475 constructionContext,
1476 attrValue,
1477 stylesheetTree.getNamespaces());
1478
1479 return true;
1480 }
1481 else
1482 {
1483 return false;
1484 }
1485 }
1486
1487
1488
1489 const XalanDOMString*
getNamespaceForPrefixInternal(const XalanDOMString & prefix) const1490 ElemTemplateElement::getNamespaceForPrefixInternal(const XalanDOMString& prefix) const
1491 {
1492 const XalanDOMString* nameSpace = 0;
1493
1494 if(getFinishedConstruction() == false)
1495 {
1496 nameSpace = getStylesheet().getNamespaceForPrefixFromStack(prefix);
1497 }
1498 else
1499 {
1500 if (equals(prefix, DOMServices::s_XMLString) == true)
1501 {
1502 nameSpace = &DOMServices::s_XMLNamespaceURI;
1503 }
1504 else
1505 {
1506 nameSpace = getNamespacesHandler().getNamespace(prefix);
1507
1508 if(nameSpace == 0)
1509 {
1510 if (m_parentNode != 0)
1511 {
1512 nameSpace = m_parentNode->getNamespaceForPrefixInternal(prefix);
1513 }
1514
1515 // Try one last time with the stylesheet...
1516 if (nameSpace == 0)
1517 {
1518 nameSpace = getStylesheet().getNamespaceForPrefix(prefix);
1519 }
1520 }
1521 }
1522 }
1523
1524 return nameSpace;
1525 }
1526
1527
1528
1529 const XalanDOMString&
getURI() const1530 ElemTemplateElement::getURI() const
1531 {
1532 return m_locatorProxy.getURI();
1533 }
1534
1535
1536
LocatorProxy(XalanFileLoc theLineNumber,XalanFileLoc theColumnNumber,const XalanDOMString & theURI)1537 ElemTemplateElement::LocatorProxy::LocatorProxy(
1538 XalanFileLoc theLineNumber,
1539 XalanFileLoc theColumnNumber,
1540 const XalanDOMString& theURI) :
1541 m_lineNumber(theLineNumber),
1542 m_columnNumber(theColumnNumber),
1543 m_uri(theURI)
1544 {
1545 }
1546
1547
1548
~LocatorProxy()1549 ElemTemplateElement::LocatorProxy::~LocatorProxy()
1550 {
1551 }
1552
1553
1554
1555 XalanFileLoc
getLineNumber() const1556 ElemTemplateElement::LocatorProxy::getLineNumber() const
1557 {
1558 return m_lineNumber;
1559 }
1560
1561
1562
1563 XalanFileLoc
getColumnNumber() const1564 ElemTemplateElement::LocatorProxy::getColumnNumber() const
1565 {
1566 return m_columnNumber;
1567 }
1568
1569
1570
1571 const XMLCh*
getPublicId() const1572 ElemTemplateElement::LocatorProxy::getPublicId() const
1573 {
1574 return 0;
1575 }
1576
1577
1578
1579 const XMLCh*
getSystemId() const1580 ElemTemplateElement::LocatorProxy::getSystemId() const
1581 {
1582 return m_uri.size() == 0 ? 0 : m_uri.c_str();
1583 }
1584
1585
1586
1587 bool
childTypeAllowed(int) const1588 ElemTemplateElement::childTypeAllowed(int /* xslToken */) const
1589 {
1590 return true;
1591 }
1592
1593
1594 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1595 const ElemTemplateElement*
getNextChildElemToExecute(StylesheetExecutionContext & executionContext,const ElemTemplateElement * currentElem) const1596 ElemTemplateElement::getNextChildElemToExecute(StylesheetExecutionContext& executionContext,
1597 const ElemTemplateElement* currentElem) const
1598 {
1599 if (hasDirectTemplate() == true)
1600 {
1601 return 0;
1602 }
1603
1604 assert(currentElem != 0);
1605
1606 const ElemTemplateElement* nextElement;
1607
1608 while((nextElement = currentElem->getNextSiblingElem()) != 0
1609 && !executeChildElement(executionContext, nextElement))
1610 {
1611 currentElem = nextElement;
1612 }
1613
1614 return nextElement;
1615
1616 }
1617
1618
1619
1620 const ElemTemplateElement*
getFirstChildElemToExecute(StylesheetExecutionContext & executionContext) const1621 ElemTemplateElement::getFirstChildElemToExecute(StylesheetExecutionContext& executionContext) const
1622 {
1623 if (hasDirectTemplate() == true)
1624 {
1625 assert(m_directTemplate != 0);
1626
1627 executionContext.pushContextMarker();
1628 executionContext.pushInvoker(this);
1629
1630 return m_directTemplate;
1631 }
1632
1633 const ElemTemplateElement * firstElement = getFirstChildElem();
1634
1635 if (firstElement != 0 && !executeChildElement(executionContext, firstElement))
1636 {
1637 firstElement = ElemTemplateElement::getNextChildElemToExecute(executionContext,firstElement);
1638 }
1639
1640 return firstElement;
1641
1642 }
1643
1644
1645
1646 bool
executeChildElement(StylesheetExecutionContext &,const ElemTemplateElement *) const1647 ElemTemplateElement::executeChildElement(
1648 StylesheetExecutionContext& /*executionContext*/,
1649 const ElemTemplateElement* /*element*/) const
1650 {
1651 return true;
1652 }
1653 #endif
1654
1655 }
1656