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 "ElemChoose.hpp"
19
20
21
22 #include <xercesc/sax/AttributeList.hpp>
23
24
25
26 #include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
27
28
29
30 #include <xalanc/XPath/XObjectFactory.hpp>
31 #include <xalanc/XPath/XPath.hpp>
32
33
34
35 #include "Constants.hpp"
36 #include "ElemWhen.hpp"
37 #include "SelectionEvent.hpp"
38 #include "Stylesheet.hpp"
39 #include "StylesheetConstructionContext.hpp"
40 #include "StylesheetExecutionContext.hpp"
41 #include "StylesheetRoot.hpp"
42
43
44
45 namespace XALAN_CPP_NAMESPACE {
46
47
48
ElemChoose(StylesheetConstructionContext & constructionContext,Stylesheet & stylesheetTree,const AttributeListType & atts,XalanFileLoc lineNumber,XalanFileLoc columnNumber)49 ElemChoose::ElemChoose(
50 StylesheetConstructionContext& constructionContext,
51 Stylesheet& stylesheetTree,
52 const AttributeListType& atts,
53 XalanFileLoc lineNumber,
54 XalanFileLoc columnNumber) :
55 ElemTemplateElement(constructionContext,
56 stylesheetTree,
57 lineNumber,
58 columnNumber,
59 StylesheetConstructionContext::ELEMNAME_CHOOSE)
60 {
61 const XalanSize_t nAttrs = atts.getLength();
62
63 for (XalanSize_t i = 0; i < nAttrs; i++)
64 {
65 const XalanDOMChar* const aname = atts.getName(i);
66
67 if (isAttrOK(
68 aname,
69 atts,
70 i,
71 constructionContext) == false &&
72 processSpaceAttr(
73 Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING.c_str(),
74 aname,
75 atts,
76 i,
77 constructionContext) == false)
78 {
79 error(
80 constructionContext,
81 XalanMessages::ElementHasIllegalAttribute_2Param,
82 Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING.c_str(),
83 aname);
84 }
85 }
86 }
87
88
89
90 const XalanDOMString&
getElementName() const91 ElemChoose::getElementName() const
92 {
93 return Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING;
94 }
95
96
97
98 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
99 const ElemTemplateElement*
startElement(StylesheetExecutionContext & executionContext) const100 ElemChoose::startElement(StylesheetExecutionContext& executionContext) const
101 {
102 ElemTemplateElement::startElement(executionContext);
103
104 XalanNode* sourceNode = executionContext.getCurrentNode();
105
106 for (const ElemTemplateElement* node = getFirstChildElem();
107 node != 0;
108 node = node->getNextSiblingElem())
109 {
110 const int type = node->getXSLToken();
111
112 if (StylesheetConstructionContext::ELEMNAME_WHEN == type)
113 {
114
115 const XPath* const theXPath = node->getXPath(0);
116 assert(theXPath != 0);
117
118 bool test;
119
120 theXPath->execute(*this, executionContext, test);
121
122 if (0 != executionContext.getTraceListeners())
123 {
124 executionContext.fireSelectEvent(
125 SelectionEvent(executionContext,
126 sourceNode,
127 *node,
128 Constants::ATTRNAME_TEST,
129 *theXPath,
130 test));
131 }
132
133 if(test == true)
134 {
135 return node;
136 }
137 }
138 else
139 {
140 // xsl:otherwise
141 return node;
142 }
143 }
144 return 0;
145 }
146
147
148
149 const ElemTemplateElement*
getNextChildElemToExecute(StylesheetExecutionContext &,const ElemTemplateElement *) const150 ElemChoose::getNextChildElemToExecute(
151 StylesheetExecutionContext& /*executionContext*/,
152 const ElemTemplateElement* /*currentElem*/) const
153 {
154 return 0;
155 }
156 #endif
157
158
159
160 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
161 void
execute(StylesheetExecutionContext & executionContext) const162 ElemChoose::execute(StylesheetExecutionContext& executionContext) const
163 {
164 ElemTemplateElement::execute(executionContext);
165
166 XalanNode* sourceNode = executionContext.getCurrentNode();
167
168 for (const ElemTemplateElement* node = getFirstChildElem();
169 node != 0;
170 node = node->getNextSiblingElem())
171 {
172 const int type = node->getXSLToken();
173
174 if(StylesheetConstructionContext::ELEMNAME_WHEN == type)
175 {
176
177 const XPath* const theXPath = node->getXPath(0);
178 assert(theXPath != 0);
179
180 bool test;
181
182 theXPath->execute(*this, executionContext, test);
183
184 if(0 != executionContext.getTraceListeners())
185 {
186 executionContext.fireSelectEvent(
187 SelectionEvent(executionContext,
188 sourceNode,
189 *node,
190 Constants::ATTRNAME_TEST,
191 *theXPath,
192 test));
193 }
194
195 if(test == true)
196 {
197 node->execute(executionContext);
198
199 break;
200 }
201 }
202 else
203 {
204 // xsl:otherwise
205 node->execute(executionContext);
206 }
207 }
208 }
209 #endif
210
211
212
213 bool
childTypeAllowed(int xslToken) const214 ElemChoose::childTypeAllowed(int xslToken) const
215 {
216 bool fResult = false;
217
218 switch(xslToken)
219 {
220 // char-instructions
221 case StylesheetConstructionContext::ELEMNAME_WHEN:
222 case StylesheetConstructionContext::ELEMNAME_OTHERWISE:
223 fResult = true;
224 break;
225
226 default:
227 break;
228 }
229
230 return fResult;
231 }
232
233
234
235 }
236