2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
12 * The Original Code is the Sablotron XSLT Processor.
14 * The Initial Developer of the Original Code is Ginger Alliance Ltd.
15 * Portions created by Ginger Alliance are Copyright (C) 2000-2002
16 * Ginger Alliance Ltd. All Rights Reserved.
20 * Alternatively, the contents of this file may be used under the
21 * terms of the GNU General Public License Version 2 or later (the
22 * "GPL"), in which case the provisions of the GPL are applicable
23 * instead of those above. If you wish to allow use of your
24 * version of this file only under the terms of the GPL and not to
25 * allow others to use your version of this file under the MPL,
26 * indicate your decision by deleting the provisions above and
27 * replace them with the notice and other provisions required by
28 * the GPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under either the MPL or the
37 #define SablotAsExport
46 #include "guard.h" // GP: clean
47 #include "numbering.h"
49 #include "domprovider.h"
52 #ifdef SABLOT_DEBUGGER
60 /*****************************************************************
62 *****************************************************************/
75 typedef AttTableItem AttTable[];
76 //declarations using AttTable doesn't work with Sun CC.
78 AttTableItem at_empty[] =
80 {XSLA_NONE, FALSE, FALSE, EX_NONE}
82 AttTableItem at_apply_templates[] =
84 {XSLA_SELECT, FALSE, FALSE, EX_NODESET},
85 {XSLA_MODE, FALSE, FALSE, EX_NONE}
87 AttTableItem at_attribute[] =
89 {XSLA_NAME, TRUE, TRUE, EX_STRING},
90 {XSLA_NAMESPACE, FALSE, TRUE, EX_STRING}
92 AttTableItem at_attribute_set[] =
94 {XSLA_NAME, TRUE, FALSE, EX_NONE},
95 {XSLA_USE_ATTR_SETS, FALSE, FALSE, EX_NONE},
97 AttTableItem at_call_template[] =
99 {XSLA_NAME, TRUE, FALSE, EX_NONE}
101 AttTableItem at_copy[] =
103 {XSLA_USE_ATTR_SETS, FALSE, FALSE, EX_NONE}
105 AttTableItem at_copy_of[] =
107 {XSLA_SELECT, TRUE, FALSE, EX_UNKNOWN}
109 AttTableItem at_decimal_format[] =
111 {XSLA_NAME, FALSE, FALSE, EX_NONE},
112 {XSLA_DECIMAL_SEPARATOR, FALSE, FALSE, EX_NONE},
113 {XSLA_GROUPING_SEPARATOR, FALSE, FALSE, EX_NONE},
114 {XSLA_INFINITY, FALSE, FALSE, EX_NONE},
115 {XSLA_MINUS_SIGN, FALSE, FALSE, EX_NONE},
116 {XSLA_NAN, FALSE, FALSE, EX_NONE},
117 {XSLA_PERCENT, FALSE, FALSE, EX_NONE},
118 {XSLA_PER_MILLE, FALSE, FALSE, EX_NONE},
119 {XSLA_ZERO_DIGIT, FALSE, FALSE, EX_NONE},
120 {XSLA_DIGIT, FALSE, FALSE, EX_NONE},
121 {XSLA_PATTERN_SEPARATOR, FALSE, FALSE, EX_NONE}
123 AttTableItem at_element[] =
125 {XSLA_NAME, TRUE, TRUE, EX_STRING},
126 {XSLA_NAMESPACE, FALSE, TRUE, EX_STRING},
127 {XSLA_USE_ATTR_SETS, FALSE, FALSE, EX_NONE}
129 AttTableItem at_for_each[] =
131 {XSLA_SELECT, TRUE, FALSE, EX_NODESET}
133 AttTableItem at_if[] =
135 {XSLA_TEST, TRUE, FALSE, EX_BOOLEAN}
137 AttTableItem at_import[] =
139 {XSLA_HREF, TRUE, FALSE, EX_NONE}
141 AttTableItem at_include[] =
143 {XSLA_HREF, TRUE, FALSE, EX_NONE}
145 AttTableItem at_key[] =
147 {XSLA_NAME, TRUE, FALSE, EX_NONE},
148 {XSLA_MATCH, TRUE, FALSE, EX_NODESET_PATTERN},
149 {XSLA_USE, TRUE, FALSE, EX_UNKNOWN}
151 AttTableItem at_message[] =
153 {XSLA_TERMINATE, FALSE, FALSE, EX_NONE}
155 AttTableItem at_ns_alias[] =
157 {XSLA_STYLESHEET_PREFIX, TRUE, FALSE, EX_NONE},
158 {XSLA_RESULT_PREFIX, TRUE, FALSE, EX_NONE}
160 AttTableItem at_number[] =
162 {XSLA_LEVEL, FALSE, FALSE, EX_NONE},
163 {XSLA_COUNT, FALSE, FALSE, EX_NODESET_PATTERN},
164 {XSLA_FROM, FALSE, FALSE, EX_NODESET_PATTERN},
165 {XSLA_VALUE, FALSE, FALSE, EX_NUMBER},
166 {XSLA_FORMAT, FALSE, TRUE, EX_STRING},
167 {XSLA_LANG, FALSE, TRUE, EX_STRING},
168 {XSLA_LETTER_VALUE, FALSE, TRUE, EX_STRING},
169 {XSLA_GROUPING_SEPARATOR, FALSE, TRUE, EX_STRING},
170 {XSLA_GROUPING_SIZE, FALSE, TRUE, EX_STRING}
172 AttTableItem at_output[] =
174 {XSLA_METHOD, FALSE, FALSE, EX_NONE},
175 {XSLA_VERSION, FALSE, FALSE, EX_NONE},
176 {XSLA_ENCODING, FALSE, FALSE, EX_NONE},
177 {XSLA_OMIT_XML_DECL, FALSE, FALSE, EX_NONE},
178 {XSLA_STANDALONE, FALSE, FALSE, EX_NONE},
179 {XSLA_DOCTYPE_PUBLIC, FALSE, FALSE, EX_NONE},
180 {XSLA_DOCTYPE_SYSTEM, FALSE, FALSE, EX_NONE},
181 {XSLA_CDATA_SECT_ELEMS, FALSE, FALSE, EX_NONE},
182 {XSLA_INDENT, FALSE, FALSE, EX_NONE},
183 {XSLA_MEDIA_TYPE, FALSE, FALSE, EX_NONE}
185 AttTableItem at_param[] =
187 {XSLA_NAME, TRUE, FALSE, EX_NONE},
188 {XSLA_SELECT, FALSE, FALSE, EX_UNKNOWN}
190 AttTableItem at_preserve_space[] =
192 {XSLA_ELEMENTS, TRUE, FALSE, EX_NONE}
194 AttTableItem at_pi[] =
196 {XSLA_NAME, TRUE, TRUE, EX_STRING}
198 AttTableItem at_sort[] =
200 {XSLA_SELECT, FALSE, FALSE, EX_STRING},
201 {XSLA_LANG, FALSE, TRUE, EX_STRING},
202 {XSLA_DATA_TYPE, FALSE, TRUE, EX_STRING},
203 {XSLA_ORDER, FALSE, TRUE, EX_STRING},
204 {XSLA_CASE_ORDER, FALSE, TRUE, EX_STRING}
206 AttTableItem at_strip_space[] =
208 {XSLA_ELEMENTS, TRUE, FALSE, EX_NONE}
210 AttTableItem at_template[] =
212 {XSLA_MATCH, FALSE, FALSE, EX_NODESET_PATTERN},
213 {XSLA_NAME, FALSE, FALSE, EX_NONE},
214 {XSLA_PRIORITY, FALSE, FALSE, EX_NONE},
215 {XSLA_MODE, FALSE, FALSE, EX_NONE}
217 AttTableItem at_text[] =
219 {XSLA_DISABLE_OUTPUT_ESC, FALSE, FALSE, EX_NONE}
221 AttTableItem at_transform[] =
223 {XSLA_ID, FALSE, FALSE, EX_NONE},
224 {XSLA_EXT_ELEM_PREFIXES, FALSE, FALSE, EX_NONE},
225 {XSLA_EXCL_RES_PREFIXES, FALSE, FALSE, EX_NONE},
226 {XSLA_VERSION, TRUE, FALSE, EX_NONE}
228 AttTableItem at_value_of[] =
230 {XSLA_SELECT, TRUE, FALSE, EX_STRING},
231 {XSLA_DISABLE_OUTPUT_ESC, FALSE, FALSE, EX_NONE}
233 AttTableItem at_variable[] =
235 {XSLA_NAME, TRUE, FALSE, EX_NONE},
236 {XSLA_SELECT, FALSE, FALSE, EX_UNKNOWN}
238 AttTableItem at_when[] =
240 {XSLA_TEST, TRUE, FALSE, EX_BOOLEAN}
242 AttTableItem at_with_param[] =
244 {XSLA_NAME, TRUE, FALSE, EX_NONE},
245 {XSLA_SELECT, FALSE, FALSE, EX_UNKNOWN}
248 #define instr(code, elemflg, req, max, table) \
249 {code, elemflg, req, max, (AttTableItem*) table}
258 ELEM_CONT_PCDATA = 0x10,
259 ELEM_CONT_TOPLEVEL = 0x20,
260 ELEM_CONT_INSTR = 0x40,
261 ELEM_CONT_EXTRA = 0x80,
262 ELEM_CONT_EXTENSION = 0x100,
264 ELEM_SELF = ELEM_TOPLEVEL | ELEM_INSTR | ELEM_EXTRA,
265 ELEM_CONT = ELEM_CONT_PCDATA | ELEM_CONT_TOPLEVEL | ELEM_CONT_INSTR | ELEM_CONT_EXTRA,
267 ELEM_I0 = ELEM_INSTR,
268 ELEM_IX = ELEM_INSTR | ELEM_CONT_EXTRA,
269 ELEM_II = ELEM_INSTR | ELEM_CONT_INSTR,
270 ELEM_IT_I = ELEM_INSTR | ELEM_TOPLEVEL | ELEM_CONT_INSTR,
271 ELEM_I_XI = ELEM_INSTR | ELEM_CONT_EXTRA | ELEM_CONT_INSTR,
272 ELEM_I__ = ELEM_INSTR | ELEM_CONT_PCDATA,
274 ELEM_T0 = ELEM_TOPLEVEL,
275 ELEM_TX = ELEM_TOPLEVEL | ELEM_CONT_EXTRA,
276 ELEM_TX_I = ELEM_TOPLEVEL | ELEM_EXTRA | ELEM_CONT_INSTR,
277 ELEM_T_XI = ELEM_TOPLEVEL | ELEM_CONT_EXTRA | ELEM_CONT_INSTR,
279 ELEM_X0 = ELEM_EXTRA,
280 ELEM_XI = ELEM_EXTRA | ELEM_CONT_INSTR,
281 ELEM_X_XT = ELEM_EXTRA | ELEM_CONT_EXTRA | ELEM_CONT_TOPLEVEL |
286 struct InstrTableItem
297 instr(XSL_APPLY_IMPORTS, ELEM_I0, 0, 0, at_empty),
298 instr(XSL_APPLY_TEMPLATES, ELEM_IX, 0, 2, at_apply_templates),
299 instr(XSL_ATTRIBUTE, ELEM_II, 1, 2, at_attribute),
300 instr(XSL_ATTRIBUTE_SET, ELEM_TX, 1, 2, at_attribute_set),
301 instr(XSL_CALL_TEMPLATE, ELEM_IX, 1, 1, at_call_template),
302 instr(XSL_CHOOSE, ELEM_IX, 0, 0, at_empty),
303 instr(XSL_COMMENT, ELEM_II, 0, 0, at_empty),
304 instr(XSL_COPY, ELEM_II, 0, 1, at_copy),
305 instr(XSL_COPY_OF, ELEM_I0, 1, 1, at_copy_of),
306 instr(XSL_DECIMAL_FORMAT, ELEM_T0, 0, 11, at_decimal_format),
307 instr(XSL_ELEMENT, ELEM_II, 1, 3, at_element),
308 instr(XSL_FALLBACK, ELEM_II, 0, 0, at_empty),
309 instr(XSL_FOR_EACH, ELEM_I_XI, 1, 1, at_for_each),
310 instr(XSL_IF, ELEM_II, 1, 1, at_if),
311 instr(XSL_IMPORT, ELEM_X0, 1, 1, at_import),
312 instr(XSL_INCLUDE, ELEM_T0, 1, 1, at_include),
313 instr(XSL_KEY, ELEM_T0, 3, 3, at_key),
314 instr(XSL_MESSAGE, ELEM_II, 0, 1, at_message),
315 instr(XSL_NAMESPACE_ALIAS, ELEM_T0, 2, 2, at_ns_alias),
316 instr(XSL_NUMBER, ELEM_I0, 0, 9, at_number),
317 instr(XSL_OTHERWISE, ELEM_XI, 0, 0, at_empty),
318 instr(XSL_OUTPUT, ELEM_T0, 0, 10, at_output),
319 instr(XSL_PARAM, ELEM_TX_I, 1, 2, at_param),
320 instr(XSL_PRESERVE_SPACE, ELEM_T0, 1, 1, at_preserve_space),
321 instr(XSL_PROCESSING_INSTR, ELEM_II, 1, 1, at_pi),
322 instr(XSL_SORT, ELEM_X0, 0, 5, at_sort),
323 instr(XSL_STRIP_SPACE, ELEM_T0, 1, 1, at_strip_space),
324 instr(XSL_STYLESHEET, ELEM_X_XT, 1, 4, at_transform),
325 instr(XSL_TEMPLATE, ELEM_T_XI, 0, 4, at_template),
326 instr(XSL_TEXT, ELEM_I__, 0, 1, at_text),
327 instr(XSL_TRANSFORM, ELEM_X_XT, 1, 4, at_transform),
328 instr(XSL_VALUE_OF, ELEM_I0, 1, 2, at_value_of),
329 instr(XSL_VARIABLE, ELEM_IT_I, 1, 2, at_variable),
330 instr(XSL_WHEN, ELEM_XI, 1, 1, at_when),
331 instr(XSL_WITH_PARAM, ELEM_XI, 1, 2, at_with_param)
334 /****************************************
336 ****************************************/
341 printf("Vertex destructor >%x<\n",this);
343 // call DOM dispose callback if set
345 if (SDOM_getDisposeCallback())
346 (*(SDOM_getDisposeCallback()))(this);
350 eFlag Vertex::execute(Sit S, Context *c, Bool resolvingGlobals)
356 eFlag Vertex::value(Sit S, DStr& ret, Context *c)
362 eFlag Vertex::startCopy(Sit S, OutputterObj& out)
367 eFlag Vertex::endCopy(Sit S, OutputterObj& out)
372 eFlag Vertex::copy(Sit S, OutputterObj& out)
374 S.setCurrSAXLine(lineno); //for SAX copying - be careful
377 startDocument(S, aux);
379 OutputterObj &useOut = aux ? *aux : out;
380 E( startCopy(S, useOut) );
381 E( endCopy(S, useOut) );
388 void Vertex::speak(DStr &ret, SpeakMode mode)
392 void Vertex::setParent(Vertex *v)
397 Vertex* Vertex::getPreviousSibling()
399 if (!parent || !isElement(parent))
403 return toE(parent) -> contents[ordinal - 1];
406 Vertex* Vertex::getNextSibling()
408 if (!parent || !isElement(parent))
410 if (ordinal >= toE(parent) -> contents.number() - 1)
412 return toE(parent) -> contents[ordinal + 1];
415 const QName& Vertex::getName() const
417 return owner.getTheEmptyQName();
420 Tree& Vertex::getOwner() const
425 void Vertex::report(Sit S, MsgType type, MsgCode code, const Str& arg1, const Str& arg2) const
427 S.setCurrV((Vertex*)this);
428 S.setCurrFile(getSubtreeInfo() -> getBaseURI());
429 S.message(type, code, arg1, arg2);
432 HashTable& Vertex::dict() const
434 return getOwner().dict();
437 eFlag Vertex::serialize(Sit S, OutputterObj &out)
442 void Vertex::makeStamps(int& stamp_)
447 eFlag Vertex::getMatchingList(Sit S, Expression& match, Context& result)
452 E( match.matchesPattern(S, &aux, yes) );
458 int Vertex::getImportPrecedence()
460 return NZ( getSubtreeInfo() ) -> getStructure() -> getImportPrecedence();
463 eFlag Vertex::startDocument(Sit S, OutputterObj*& out)
466 if (outputDocument && (proc = S.getProcessor()))
468 E( proc -> startDocument(S, outputDocument) );
469 out = NZ( outputDocument -> getOutputter() );
476 eFlag Vertex::finishDocument(Sit S)
479 if (outputDocument && (proc = S.getProcessor()))
481 E( proc -> finishDocument(S, outputDocument, FALSE) );
486 /****************************************
488 ****************************************/
490 VertexList::VertexList(int logBlockSize_ /*=LIST_SIZE_SMALL*/)
491 : SList<Vertex*>(logBlockSize_)
495 VertexList::~VertexList()
500 void VertexList::destructMembers()
502 for (int i = 0; i < nItems; i++)
504 Vertex *v = (*this)[i];
513 eFlag VertexList::execute(Sit S, Context *c, Bool resolvingGlobals)
516 for (i=0; i<number(); i++)
517 E( (*this)[i] -> execute(S, c, resolvingGlobals) );
521 eFlag VertexList::value(Sit S, DStr &ret, Context *c)
527 for (i=0; i<number(); i++)
529 E( (*this)[i] -> value(S, temp, c) );
530 temp.appendSelf(ret);
535 void VertexList::speak(DStr &ret, SpeakMode mode)
538 for (i = 0; i < number(); i++)
540 (*this)[i] -> speak(ret, mode);
541 if ((mode & SM_INS_SPACES) && (i < number() - 1))
546 void VertexList::append(Vertex *v)
548 v -> ordinal = number();
549 List<Vertex*>::append(v);
552 int VertexList::strip()
555 for (int i = 0; i < number(); i++)
557 Vertex *node = (*this)[i];
558 if ((node -> vt == VT_TEXT) && isAllWhite((char*)(toText(node) -> cont)))
561 // not doing a freerm() since the node is allocated in the arena
562 // freerm(i--,FALSE);
569 eFlag VertexList::copy(Sit S, OutputterObj& out)
571 for (int i = 0; i < number(); i++)
572 E( (*this)[i] -> copy(S, out) );
576 void VertexList::insertBefore(Vertex *newChild, int refIndex)
578 PList<Vertex*>::insertBefore(newChild, refIndex);
579 for (int i = refIndex; i < number(); i++)
580 (*this)[i] -> ordinal = i;
583 void VertexList::rm(int ndx)
585 SList<Vertex*>::rm(ndx);
586 for (int i = ndx; i < number(); i++)
587 (*this)[i] -> ordinal = i;
590 int VertexList::getIndex(Vertex *v)
592 for (int i = 0; i < number(); i++)
593 if ((*this)[i] == v) return i;
597 eFlag VertexList::serialize(Sit S, OutputterObj &out)
600 for (i = 0; i < number(); i++)
601 E( (*this)[i] -> serialize(S, out) );
605 void VertexList::makeStamps(int& stamp_)
607 for (int i = 0; i < number(); i++)
608 (*this)[i] -> makeStamps(stamp_);
611 eFlag VertexList::getMatchingList(Sit S, Expression& match, Context& result)
613 for (int i = 0; i < number(); i++)
614 E( (*this)[i] -> getMatchingList(S, match, result) );
618 /****************************************
620 a vertex with contents
621 ****************************************/
623 Daddy::Daddy(Tree& owner_, VTYPE avt /* = VT_DADDY_WF */)
624 : Vertex(owner_, avt), contents(&(owner_.getArena()))
631 // not doing freeall since it's all in the arena
632 // contents.freeall(FALSE);
633 contents.destructMembers();
636 eFlag Daddy::execute(Sit S, Context *c, Bool resolvingGlobals)
638 E( contents.execute(S, c, resolvingGlobals) );
642 eFlag Daddy::value(Sit S, DStr &ret, Context *c)
644 E( contents.value(S, ret, c) );
648 eFlag Daddy::checkChildren(Sit S)
650 assert(!"Daddy::checkChildren()");
654 eFlag Daddy::newChild(Sit S, Vertex *v)
656 // contents.appendAndSetOrdinal(v);
658 v -> setParent(this);
662 void Daddy::speak(DStr &ret, SpeakMode mode)
664 if (mode & SM_CONTENTS)
665 contents.speak(ret, mode);
670 return contents.strip();
673 eFlag Daddy::getMatchingList(Sit S, Expression& match, Context& result)
675 E( Vertex::getMatchingList(S, match, result) );
676 E( contents.getMatchingList(S, match, result) );
682 /****************************************
684 a vertex with prolog and contents
685 ****************************************/
687 RootNode::~RootNode()
691 eFlag RootNode::execute(Sit S, Context *c, Bool resolvingGlobals)
695 E( Daddy::execute(S, c, resolvingGlobals) );
699 eFlag RootNode::checkChildren(Sit S)
704 eFlag RootNode::newChild(Sit S, Vertex *v)
708 E( Daddy::newChild(S, v) );
712 void RootNode::speak(DStr &s, SpeakMode mode)
714 if (mode & SM_DESCRIBE)
716 if (mode & SM_CONTENTS)
717 Daddy::speak(s,mode);
720 eFlag RootNode::startCopy(Sit S, OutputterObj& out)
722 return Vertex::startCopy(S, out);
725 eFlag RootNode::endCopy(Sit S, OutputterObj& out)
727 return Vertex::endCopy(S, out);
730 eFlag RootNode::copy(Sit S, OutputterObj& out)
732 //RootNode shouldn't need to case for outputDocument
734 E( startCopy(S, out) );
735 E( contents.copy(S, out) );
736 E( endCopy(S, out) );
740 eFlag RootNode::serialize(Sit S, OutputterObj &out)
742 E( out.eventBeginOutput(S) );
743 E( contents.serialize(S, out) );
744 E( out.eventEndOutput(S) );
748 /****************************************
750 a vertex with attributes, defs and contents
751 ****************************************/
753 Element::Element(Tree& owner_, QName& aqname, VTYPE avt /*= VT_ELEMENT_WF*/)
754 : Daddy(owner_, avt),
755 namespaces(&(owner_.getArena())),
756 atts(&(owner_.getArena()))
759 //origContext = NULL;
763 preserveSpace = FALSE;
764 #ifdef SABLOT_DEBUGGER
771 // not doing freeall since it's all in the arena
772 // namespaces.freeall(FALSE);
773 // atts.freeall(FALSE);
775 attsNames -> freeall(FALSE);
778 namespaces.destructMembers();
779 atts.destructMembers();
785 return contents.strip();
790 eFlag Element::execute(Sit S, Context *c, Bool resolvingGlobals)
792 #ifdef SABLOT_DEBUGGER
793 if (debugger) E( debugger -> breakOnElement(S, this, c) );
797 owner.expandQ(name, expandedName);
798 OutputterObj * out = NZ(S.getProcessor()) -> outputter();
801 Bool aliased = false;
802 NZ(S.getProcessor()) -> getAliasedName(expandedName, aliased);
804 //set subtree for exclusions
805 E( out -> eventElementStart(S, expandedName) );
806 //output namespaces (and extra aliased namespace if needed)
807 E( namespaces.executeSkip(S, c, resolvingGlobals, expandedName, aliased) );
809 E( out -> eventNamespace(S, expandedName.getPrefix(),
810 expandedName.getUri() ) )
812 if (attSetNames(FALSE))
813 E( executeAttributeSets(S, c, resolvingGlobals) );
815 E( atts.execute(S, c, resolvingGlobals) );
817 E( Daddy::execute(S, c, resolvingGlobals) );
820 E( out -> eventElementEnd(S, expandedName));
825 eFlag Element::executeFallback(Sit S, Context *c, Bool &hasSome,
826 Bool resolvingGlobals)
828 Processor *proc = NZ(S.getProcessor());
829 for (int i = 0; i < contents.number(); i++)
831 Vertex *v = contents[i];
832 if (isXSLElement(v) && (toX(v) -> op == XSL_FALLBACK) )
834 proc -> vars -> startApplyOne();
835 E( toE(v) -> contents.execute(S, c, resolvingGlobals) );
836 proc -> vars -> endApplyOne();
843 eFlag Element::newChild(Sit S, Vertex *v)
845 v -> setParent(this);
848 // atts.appendAndSetOrdinal(v);
852 namespaces.append(v);
853 // namespaces.appendAndSetOrdinal(v);
855 E( Daddy::newChild(S, v) );
860 void Element::speak(DStr &ret, SpeakMode mode)
862 if (mode & (SM_NAME | SM_CONTENTS))
866 owner.expandQStr(name, fullName);
868 // name.speak(ret,mode);
869 if (mode & SM_CONTENTS)
871 if (namespaces.number())
874 namespaces.speak(ret, (SpeakMode)(mode | SM_INS_SPACES));
879 atts.speak(ret, (SpeakMode)(mode | SM_INS_SPACES));
883 contents.speak(ret,(SpeakMode)(mode & ~SM_INS_SPACES));
886 // name.speak(ret,mode);
894 /*================================================================
896 This removes all VARIABLE bindings for the variables
897 that are children of this element. The param and with-param
898 bindings are removed by the 'vars' list itself.
899 ================================================================*/
901 void Element::removeBindings(Sit S)
905 for (int i = contents.number() - 1; i >= 0; i--)
908 if (isXSLElement(v) && (cast(XSLElement*, v) -> op == XSL_VARIABLE))
911 a = NZ(cast(XSLElement*, v) -> atts.find(XSLA_NAME));
912 // FIXME: check for error in setLogical
913 setLogical(S, q, a -> cont, FALSE);
914 NZ(S.getProcessor()) -> vars -> rmBinding(q);
919 eFlag Element::startCopy(Sit S, OutputterObj& out)
922 owner.expandQ(name, expandedName);
923 E( out.eventElementStart(S, expandedName ));
924 E( namespaces.copy(S, out) );
928 eFlag Element::endCopy(Sit S, OutputterObj& out)
931 owner.expandQ(name, expandedName);
932 E( out.eventElementEnd(S, expandedName ));
936 eFlag Element::copy(Sit S, OutputterObj& out)
939 startDocument(S, aux);
941 OutputterObj &useOut = aux ? *aux : out;
943 S.setCurrSAXLine(lineno); //for SAX copying - be careful
944 E( startCopy(S, useOut) );
945 E( atts.copy(S, useOut) );
946 E( contents.copy(S, useOut) );
947 E( endCopy(S, useOut) );
954 const QName& Element::getName() const
959 eFlag Element::setLogical(Sit S, QName &qn, const Str &string,
960 Bool defaultToo, Phrase defUri /*= UNDEF_PHRASE*/) const
963 Phrase thePrefix, resolved;
964 char *p = (char *)(Str &) string,
970 qn.setPrefix(resolved = thePrefix = dict().insert(p));
976 qn.setPrefix(resolved = thePrefix = UNDEF_PHRASE);
980 if (defUri != UNDEF_PHRASE) {
984 if (thePrefix != getOwner().stdPhrase(PHRASE_XMLNS))
986 E( namespaces.resolve(S, resolved, defaultToo) );
987 // check if a non-undef was resolved to an undef
988 if (resolved == UNDEF_PHRASE && thePrefix != UNDEF_PHRASE)
989 Err1(S, ET_BAD_PREFIX, (char *)(Str &)string);
992 resolved = UNDEF_PHRASE;
994 if (strchr(localPart,':'))
995 Err1(S, E1_EXTRA_COLON, (char *)(Str &)string);
997 qn.setLocal(dict().insert(localPart));
1001 eFlag Element::serialize(Sit S, OutputterObj &out)
1004 getOwner().expandQ(name, ename);
1005 E( out.eventElementStart(S, ename) );
1006 E( namespaces.serialize(S, out) );
1007 E( atts.serialize(S, out) );
1008 E( contents.serialize(S, out) );
1009 E( out.eventElementEnd(S, ename) );
1013 eFlag Element::serializeSubtree(Sit S, OutputterObj &out)
1015 E( out.eventBeginSubtree(S) );
1018 getOwner().expandQ(name, ename);
1019 E( out.eventElementStart(S, ename) );
1020 E( atts.serialize(S, out) );
1021 E( contents.serialize(S, out) );
1022 E( out.eventElementEnd(S, ename) );
1024 E( out.eventEndOutput(S) );
1028 void Element::removeChild(Vertex *child)
1030 assert(child -> parent == this);
1031 contents.rm(child -> ordinal);
1032 child -> setParent(NULL);
1035 void Element::makeStamps(int& stamp_)
1037 Vertex::makeStamps(stamp_);
1038 namespaces.makeStamps(stamp_);
1039 atts.makeStamps(stamp_);
1040 contents.makeStamps(stamp_);
1043 eFlag Element::getMatchingList(Sit S, Expression& match, Context& result)
1045 E( Vertex::getMatchingList(S, match, result) );
1046 E( namespaces.getMatchingList(S, match, result) );
1047 E( atts.getMatchingList(S, match, result) );
1048 E( contents.getMatchingList(S, match, result) );
1052 QNameList* Element::attSetNames(Bool canCreate) {
1053 if (!attsNames && canCreate) attsNames = new QNameList;
1057 eFlag Element::executeAttributeSets(Sit S, Context *c, Bool resolvingGlobals)
1059 Processor *proc = NZ(S.getProcessor());
1060 proc -> vars -> pushCallLevel(0);
1063 for (int i = 0; i < attsNames -> number(); i++)
1066 E( getOwner().attSets().executeAttSet(S, *((*attsNames)[i]),
1067 c, getOwner(), history,
1068 resolvingGlobals) );
1071 proc -> vars -> popCallLevel();
1075 /****************************************
1077 ****************************************/
1079 Attribute::Attribute(Tree &owner_, const QName &aqname,
1080 const Str &acont, XSL_ATT aop)
1081 : Vertex(owner_, (VTYPE) (VT_ATTRIBUTE_WF |
1082 (aop != XSLA_NONE ? VT_XSL : 0))),
1083 cont(&(owner_.getArena()))
1091 Attribute::~Attribute()
1097 eFlag findAVTBrace(Sit S, char *&p, char which, DStr ©buf)
1099 char *p0 = p; // ,c;
1108 if (*(p+1) == which)
1112 copybuf.nadd(p0, len);
1120 if (len) copybuf.nadd(p0, len);
1124 eFlag Attribute::buildExpr(Sit S, Bool asTemplate, ExType ty)
1127 GP( Expression ) eadd;
1131 expr = new Expression(*toE(parent), EXF_STRINGSEQ); // GP: OK
1132 char *p = (char*) cont;
1135 E( findAVTBrace(S, q = p, '{', sadd) );
1136 if (!sadd.isEmpty())
1138 eadd = new Expression(*toE(parent), EXF_ATOM);
1139 (*eadd).setAtom(sadd);
1140 expr -> args.append(eadd.keep());
1144 if (!*(p = q + 1)) break;
1145 E( findAVTBrace(S, q = p, '}',sadd) );
1146 if (!sadd.isEmpty())
1148 eadd = new Expression(*toE(parent));
1149 E( (*eadd).parse(S, sadd));
1150 expr -> args.append(eadd.keep());
1158 expr = new Expression(*toE(parent)); // GP: OK
1159 E( expr -> parse(S, cont, (Bool) (ty == EX_NODESET_PATTERN)) );
1164 eFlag Attribute::execute(Sit S, Context *c, Bool resolvingGlobals)
1168 owner.expandQ(name, ename);
1169 OutputterObj &out = *(NZ(S.getProcessor()) -> outputter());
1171 if (isXSLElement(parent) || op != XSLA_NONE ||
1172 ename.getUri() == theXSLTNamespace )
1177 E( out.eventAttributeStart(S, ename) );
1179 E( value(S, temp,c) );
1180 E( out.eventData(S, temp) );
1181 E( out.eventAttributeEnd(S) );
1185 eFlag Attribute::value(Sit S, DStr &ret, Context *c)
1189 Expression temp(*toE(parent));
1190 E( expr -> eval(S, temp, c) );
1191 E( temp.tostring(S, ret) );
1198 void Attribute::speak(DStr &ret, SpeakMode mode)
1200 if (mode & (SM_NAME | SM_CONTENTS))
1203 owner.expandQStr(name, fullName);
1205 // name.speak(ret,mode);
1207 if (mode & SM_CONTENTS)
1210 // escape whitespace and quotes in value
1212 const char* escNTQLG[] =
1213 {escNewline, escTab, escQuote, escLess, escGreater, NULL};
1214 escapeChars(escapedCont, cont, "\n\t\"<>", escNTQLG);
1215 escapedCont.appendSelf(ret);
1220 eFlag Attribute::startCopy(Sit S, OutputterObj& out)
1223 owner.expandQ(name, ename);
1224 E( out.eventAttributeStart(S, ename) );
1225 E( out.eventData(S, cont) );
1226 E( out.eventAttributeEnd(S) );
1230 const QName& Attribute::getName() const
1235 void Attribute::setValue(const Str& newValue)
1240 eFlag Attribute::serialize(Sit S, OutputterObj &out)
1243 getOwner().expandQ(name, ename);
1244 E( out.eventAttributeStart(S, ename) );
1245 E( out.eventData(S, cont) );
1246 E( out.eventAttributeEnd(S) );
1250 /****************************************
1252 ****************************************/
1254 Attribute* AttList::find(XSL_ATT what)
1259 for (i = 0; i < num; i++)
1261 // need to use a temporary variable
1262 // to get around Solaris template problem
1263 Vertex * pTemp = (*this)[i];
1264 a = cast(Attribute *, pTemp);
1265 if (a -> op == what)
1271 int AttList::findNdx(const QName& attName)
1276 for (i = 0; i < num; i++)
1278 // need to use a temporary variable
1279 // to get around Solaris template problem
1280 Vertex * pTemp = (*this)[i];
1282 if (attName == a -> getName())
1288 Attribute* AttList::find(const QName& attName)
1290 int ndx = findNdx(attName);
1291 // need to use a temporary variable
1292 // to get around Solaris template problem
1295 Vertex * pTemp = (*this)[ndx];
1304 /*****************************************************************
1306 *****************************************************************/
1307 //NmSpace::NmSpace(Tree& owner_, Phrase _prefix, Phrase _uri, NsKind _kind)
1308 NmSpace::NmSpace(Tree& owner_, Phrase _prefix, Phrase _uri,
1309 Bool _excluded, NsKind _kind)
1310 : Vertex(owner_, VT_NAMESPACE)
1314 name.setLocal(prefix);
1316 excluded = _excluded;
1324 eFlag NmSpace::execute(Sit S, Context *c, Bool resolvingGlobals)
1328 E( NZ(S.getProcessor()) -> outputter() ->
1330 //was: proc -> aliasXL(prefix)),
1331 getOwner().dict().getKey(prefix),
1332 getOwner().dict().getKey(uri),
1338 eFlag NmSpace::executeSkip(Sit S, Context *c, Bool resolvingGlobals,
1339 EQName & exName, Bool aliased)
1343 const Str & pStr = getOwner().dict().getKey(prefix);
1344 const Str & uStr = getOwner().dict().getKey(uri);
1346 if (!aliased || !(exName.getPrefix() == pStr))
1347 E( NZ(S.getProcessor()) -> outputter() ->
1348 eventNamespace(S, pStr, uStr, excluded) );
1352 void NmSpace::speak(DStr& s, SpeakMode mode)
1355 if (prefix != UNDEF_PHRASE)
1358 s += getOwner().dict().getKey(prefix);
1361 s += getOwner().dict().getKey(uri);
1365 eFlag NmSpace::value(Sit S, DStr &s, Context *c)
1367 s = getOwner().dict().getKey(uri);
1371 eFlag NmSpace::startCopy(Sit S, OutputterObj& out)
1373 E( out.eventNamespace(S,
1374 getOwner().dict().getKey(prefix),
1375 getOwner().dict().getKey(uri),
1380 const QName& NmSpace::getName() const
1385 eFlag NmSpace::serialize(Sit S, OutputterObj &out)
1387 const Str &prefixStr = getOwner().expand(prefix),
1388 &uriStr = getOwner().expand(uri);
1389 // hide the "xml" binding
1390 if (!(prefixStr == "xml"))
1391 E( out.eventNamespace(S, prefixStr, uriStr) );
1395 NsKind NmSpace::setKind(NsKind kind_) {
1396 if (kind < kind_) kind = kind_;
1399 /*****************************************************************
1401 *****************************************************************/
1407 NmSpace* NSList::find(Phrase prefix) const
1409 int ndx = findNdx(prefix);
1410 return (ndx == -1) ? NULL : toNS((*this)[ndx]);
1413 int NSList::findNdx(Phrase prefix) const
1416 for (i = 0; i < number(); i++)
1417 if (toNS((*this)[i]) -> prefix == prefix)
1422 eFlag NSList::resolve(Sit S, Phrase &what, Bool defaultToo) const
1424 Bool emptystr = (what == UNDEF_PHRASE);
1425 if (emptystr && !defaultToo)
1427 NmSpace *p = find(what);
1431 what = UNDEF_PHRASE;
1438 void NSList::unresolve(Phrase &what) const
1440 assert(what != UNDEF_PHRASE);
1442 for (int i = 0; i < number(); i++)
1444 currNS = toNS((*this)[i]);
1445 if (what == currNS -> uri)
1447 what = currNS -> prefix;
1455 appends all current namespace declarations as vertices to tree t
1456 'other' is the list where they are being appended in t
1459 void NSList::giveCurrent(Sit S, NSList &other, Tree *t, int nscount) const
1461 const NmSpace *currNS, *addedNS;
1462 const int imax = number() - 1;
1463 UriList &excludedNS = t -> getCurrentInfo() -> getExcludedNS();
1464 for (int i = imax; i >= 0; i--)
1466 currNS = toNS((*this)[i]);
1467 if (other.findNdx(currNS -> prefix) == -1) {
1468 addedNS = new(&(NZ(t) -> getArena()))
1469 NmSpace(*t, currNS -> prefix, currNS -> uri,
1470 excludedNS.findNdx(currNS->uri)!=-1 || currNS->excluded,
1471 i > (imax - nscount) ? NSKIND_DECLARED : NSKIND_PARENT);
1472 t -> appendVertex(S, toV(addedNS));
1473 // _JP_ ??? why not other.append(toV(addedNS));
1478 void NSList::swallow(Sit S, NSList &other, Tree* srcTree, Tree *t)
1480 for (int i = 0; i < other.number(); i++)
1482 NmSpace *currNS = toNS(other[i]);
1485 //translate between dictionaries
1486 if (srcTree && srcTree != t)
1488 if (currNS -> prefix == UNDEF_PHRASE)
1493 const Str &aux1 = srcTree -> expand(currNS -> prefix);
1494 p = t -> unexpand(aux1);
1497 const Str &aux2 = srcTree -> expand(currNS -> uri);
1498 u = t -> unexpand(aux2);
1503 p = currNS -> prefix;
1507 NmSpace *nm = new (&(NZ(t) -> getArena())) NmSpace(*t, p, u, NSKIND_PARENT);
1513 void NSList::findPrefix(QName &q)
1515 if (q.getUri() == UNDEF_PHRASE)
1516 q.setPrefix(UNDEF_PHRASE);
1519 Phrase thePrefix = q.getUri();
1520 unresolve(thePrefix);
1521 q.setPrefix(thePrefix);
1525 void NSList::report(Sit S, MsgType type, MsgCode code,
1526 const Str &arg1, const Str &arg2) const
1528 S.message(type, code, arg1, arg2);
1531 void NSList::setPrefixKind(Phrase prefix_, NsKind kind_) const
1533 int ndx = findNdx(prefix_);
1535 toNS((*this)[ndx]) -> setKind(kind_);
1539 void NSList::incPrefixUsage(Phrase prefix_) const
1541 int ndx = findNdx(prefix_);
1543 toNS((*this)[ndx]) -> usageCount++;
1547 void NSList::decPrefixUsage(Phrase prefix_) const
1549 int ndx = findNdx(prefix_);
1551 toNS((*this)[ndx]) -> usageCount--;
1555 eFlag NSList::executeSkip(Sit S, Context * c, Bool resolvingGlobals,
1556 EQName & exName, Bool aliased)
1559 for (i=0; i<number(); i++)
1560 E( toNS((*this)[i]) -> executeSkip(S, c, resolvingGlobals,
1565 /****************************************
1567 ****************************************/
1569 Text::Text(Tree& owner_, char *acont, int alen /* =0 */)
1570 : Vertex(owner_, VT_TEXT_WF), cont(&(owner_.getArena()))
1573 cont.nset(acont,alen);
1574 else cont = (char*) acont;
1575 isCDATAFlag = FALSE;
1582 eFlag Text::execute(Sit S, Context *c, Bool resolvingGlobals)
1584 E( NZ(S.getProcessor()) -> outputter() -> eventData(S, cont) );
1588 eFlag Text::value(Sit S, DStr& ret, Context *c)
1594 void Text::speak(DStr &ret, SpeakMode mode)
1596 if (mode & SM_ESCAPE)
1597 cont.speakTerse(ret);
1602 eFlag Text::startCopy(Sit S, OutputterObj& out)
1604 E( out.eventData(S, cont) );
1608 eFlag Text::serialize(Sit S, OutputterObj &out)
1611 E( out.eventCDataSection(S, cont) )
1613 E( out.eventData(S, cont) );
1617 void Text::beCDATA()
1622 Bool Text::isCDATA()
1627 /****************************************
1629 ****************************************/
1631 Comment::Comment(Tree& owner_, const Str& cont_)
1633 Vertex(owner_, VT_COMMENT), cont(&(owner_.getArena()))
1642 eFlag Comment::execute(Sit S, Context *c, Bool resolvingGlobals)
1647 eFlag Comment::value(Sit S, DStr& ret, Context *c)
1653 void Comment::speak(DStr &ret, SpeakMode mode)
1658 eFlag Comment::startCopy(Sit S, OutputterObj& out)
1660 E( out.eventCommentStart(S) );
1661 E( out.eventData(S, cont) );
1662 E( out.eventCommentEnd(S) );
1666 eFlag Comment::serialize(Sit S, OutputterObj &out)
1668 E( out.eventCommentStart(S) );
1669 E( out.eventData(S, cont) );
1670 E( out.eventCommentEnd(S) );
1674 /****************************************
1676 ****************************************/
1678 ProcInstr::ProcInstr(Tree& owner_, Phrase name_, const Str& cont_)
1680 Vertex(owner_, VT_PI), cont(&(owner_.getArena()))
1683 name.setLocal(name_);
1687 ProcInstr::~ProcInstr()
1691 eFlag ProcInstr::execute(Sit S, Context *c, Bool resolvingGlobals)
1696 eFlag ProcInstr::value(Sit S, DStr& ret, Context *c)
1702 void ProcInstr::speak(DStr &ret, SpeakMode mode)
1707 eFlag ProcInstr::startCopy(Sit S, OutputterObj& out)
1709 E( out.eventPIStart(S, owner.expand(name.getLocal())) );
1710 E( out.eventData(S, cont) );
1711 E( out.eventPIEnd(S) );
1715 const QName& ProcInstr::getName() const
1720 eFlag ProcInstr::serialize(Sit S, OutputterObj &out)
1722 const Str& nameStr = getOwner().expand(name.getLocal());
1723 E( out.eventPIStart(S, nameStr) );
1724 E( out.eventData(S, cont) );
1725 E( out.eventPIEnd(S) );
1729 /****************************************
1731 ****************************************/
1733 XSLElement::XSLElement(Tree& owner_, QName& aqname, XSL_OP code)
1735 Element(owner_, aqname, VT_XSL_ELEMENT_WF)
1737 assert(code != XSL_NONE);
1742 eFlag XSLElement::newChild(Sit S, Vertex *v)
1746 E( Element::newChild(S, v) );
1750 eFlag XSLElement::execute(Sit S, Context *c, Bool resolvingGlobals)
1753 Bool didNotExecute = FALSE;
1754 Processor *proc = NZ(S.getProcessor());
1756 if (c -> isFinished())
1759 //c->setCurrentNode(NULL); _cn_
1761 NodeHandle v = c -> current();
1764 //we store the current context to the element
1765 //e.g. the current() function needs it
1766 //setOrigContext(c);
1768 #ifdef SABLOT_DEBUGGER
1769 if (debugger) E( debugger -> breakOnElement(S, this, c) );
1774 case XSL_APPLY_TEMPLATES:
1776 Attribute *aSelect = atts.find(XSLA_SELECT);
1779 e.assign( NZ(aSelect -> expr) );
1782 e = new Expression(*this, EXF_LOCPATH);
1789 Bool addedMode = TRUE;
1790 a = atts.find(XSLA_MODE);
1793 GP( QName ) m = new QName;
1794 E( setLogical(S, *m, a -> cont,FALSE) );
1795 proc -> pushMode(m.keep());
1797 else if (proc -> getCurrentMode())
1798 proc -> pushMode(NULL);
1799 else addedMode = FALSE;
1803 E( (*e).createContext( S, newc ) );
1805 if (!(*newc).isVoid())
1807 // *** SORT HERE ***
1808 SortDefList sortDefs;
1809 makeSortDefs(S, sortDefs, c);
1810 if (sortDefs.number())
1811 E( (*newc).sort(S, this, &sortDefs) );
1812 sortDefs.freeall(FALSE);
1814 // process with-params
1815 E( contents.execute(S, c, resolvingGlobals) );
1816 // proc will dispose of newc:
1817 E( proc -> execute(S, (Vertex*) NULL, newc, resolvingGlobals) );
1819 // remove the prebindings introduced by with-param
1820 proc -> vars -> rmPrebindings();
1823 newc.del(); // GP: done automatically anyway
1827 e.del(); // GP: done automatically anyway
1830 case XSL_APPLY_IMPORTS:
1832 E( proc -> execApplyImports(S, c, subtree, resolvingGlobals) );
1837 a = NZ( atts.find(XSLA_TEST) );
1838 Expression boolexpr(*this);
1839 E( NZ(a -> expr) -> eval(S, boolexpr,c) );
1840 Bool boolval = boolexpr.tobool();
1841 if ((boolval) && (contents.number()))
1842 E( contents.execute(S, c, resolvingGlobals) )
1844 didNotExecute = TRUE;
1849 for (int i = 0; i < contents.number() && !done; i++)
1851 // need to use a temporary variable
1852 // to get around Solaris template problem
1853 Vertex * pTemp = contents[i];
1854 XSLElement *x = cast(XSLElement*,pTemp);
1855 //needed for the current() function
1856 //problem was, that trueFor is called before x -> execute
1857 //x -> setOrigContext(c);
1858 if (x -> op == XSL_WHEN)
1860 a = NZ( x -> atts.find(XSLA_TEST) );
1861 Expression boolexpr(*this);
1862 E( NZ(a -> expr) -> eval(S, boolexpr, c) );
1863 done = boolexpr.tobool();
1866 E( x -> execute(S, c, resolvingGlobals) );
1870 assert(x -> op == XSL_OTHERWISE);
1871 E( x -> execute(S, c, resolvingGlobals) );
1875 case XSL_WHEN: // condition tested by CHOOSE
1877 E( contents.execute(S, c, resolvingGlobals) );
1879 case XSL_OTHERWISE: // condition tested by CHOOSE
1881 E( contents.execute(S, c, resolvingGlobals) );
1887 E( NZ( atts.find(XSLA_NAME) ) -> value(S, nameStr, c) );
1888 if (! isValidQName((char*)nameStr) )
1889 Err1(S, E_INVALID_QNAME, (char*)nameStr);
1891 Phrase nsuri = UNDEF_PHRASE;
1893 //prepare for namespace handling
1894 Attribute *a = atts.find(XSLA_NAMESPACE);
1896 E( a -> value(S, uristr, c) );
1897 nsuri = owner.unexpand(uristr);
1900 E( setLogical(S, q, nameStr, TRUE, nsuri) );
1902 Str prefix = owner.expand(q.getPrefix());
1903 if (nsuri != UNDEF_PHRASE &&
1904 (q.getPrefix() == UNDEF_PHRASE || prefix == "xmlns"))
1906 Str pfx = S.getProcessor() -> getNextNSPrefix();
1907 q.setPrefix(owner.unexpand(pfx));
1911 owner.expandQ(q, ename);
1913 E( proc -> outputter() -> eventElementStart(S, ename) );
1914 //we have to inherit namespaces
1915 E( namespaces.execute(S, c, resolvingGlobals) );
1916 //add namespace from 'namespace' attribute
1919 prefix = ename.getPrefix();
1920 proc -> outputter() -> eventNamespace(S, prefix, uristr);
1922 //execute attribute sets
1923 E( executeAttributeSets(S, c, resolvingGlobals) );
1925 E( Daddy::execute(S, c, resolvingGlobals) );
1926 E( proc -> outputter() -> eventElementEnd(S, ename) );
1929 case XSL_PROCESSING_INSTR:
1933 E( NZ( atts.find(XSLA_NAME) ) -> value(S, nameStr, c) );
1934 if (! isValidNCName((char*)nameStr) )
1935 Err1(S, E_INVALID_NCNAME, (char*)nameStr);
1937 E( setLogical(S, q, nameStr, FALSE) );
1938 const Str& qloc = owner.expand(q.getLocal());
1939 if (( q.getPrefix() != UNDEF_PHRASE ) ||
1940 strEqNoCase( qloc, "xml") || (qloc == "") )
1941 Err1(S, E1_PI_TARGET, nameStr);
1942 E( proc -> outputter() -> eventPIStart( S, qloc ) );
1943 E( contents.execute(S, c, resolvingGlobals) );
1944 //for better error report
1945 eFlag flg = proc -> outputter() -> eventPIEnd(S);
1946 if (S.getError() == E_INVALID_DATA_IN_PI)
1947 Err(S, E_INVALID_DATA_IN_PI);
1952 E( proc -> outputter() -> eventCommentStart(S) );
1953 E( contents.execute(S, c, resolvingGlobals) );
1954 E( proc -> outputter() -> eventCommentEnd(S) );
1960 E( NZ( atts.find(XSLA_NAME) ) -> value(S, nameStr, c) );
1961 if (! isValidQName((char*)nameStr) )
1962 Err1(S, E_INVALID_QNAME, (char*)nameStr);
1964 Phrase nsuri = UNDEF_PHRASE;
1966 //prepare for namespace handling
1967 Attribute *a = atts.find(XSLA_NAMESPACE);
1969 E( a -> value(S, uristr, c) );
1970 nsuri = owner.unexpand(uristr);
1973 E( setLogical(S, q, nameStr, FALSE, nsuri) );
1975 Str prefix = owner.expand(q.getPrefix());
1976 if (nsuri != UNDEF_PHRASE &&
1977 (q.getPrefix() == UNDEF_PHRASE || prefix == "xmlns"))
1980 Str pfx = S.getProcessor() -> getNextNSPrefix();
1981 q.setPrefix(owner.unexpand(pfx));
1985 owner.expandQ(q, ename);
1987 //output new namespace if needed
1990 prefix = ename.getPrefix();
1991 proc -> outputter() -> eventNamespace(S, prefix, uristr);
1994 E( proc -> outputter() -> eventAttributeStart(S, ename) );
1995 E( contents.execute(S, c, resolvingGlobals) );
1996 E( proc -> outputter() -> eventAttributeEnd(S) );
2000 Attribute *disableEsc = atts.find(XSLA_DISABLE_OUTPUT_ESC);
2001 if (disableEsc && disableEsc -> cont == (const char*)"yes")
2002 E( proc -> outputter() -> eventDisableEscapingForNext(S) );
2003 E( contents.execute(S, c, resolvingGlobals) );
2007 proc -> vars -> startApplyOne();
2008 E( Daddy::execute(S, c, resolvingGlobals) );
2009 proc -> vars -> endApplyOne();
2011 case XSL_FALLBACK: //simply does nothing
2013 case XSL_STYLESHEET:
2016 GP( Context ) newc = c -> copy();
2018 Processor *proc = NZ(S.getProcessor());
2022 //E( getOwner().resolveGlobals(S, c, S.getProcessor()) );
2023 // process other top level elements
2024 for (int i = 0; i < contents.number(); i++)
2026 Vertex *son = contents[i];
2027 if (isXSLElement(son) && (instrTable[toX(son) -> op].flags & ELEM_TOPLEVEL))
2029 switch(toX(son) -> op)
2033 // global vars have been executed before
2040 E( proc -> resolveGlobal(S, c, temp, toX(son)) );
2042 default: E( son -> execute(S, c, resolvingGlobals) );
2045 //execute top-level extension elements as well
2046 if ( isExtension(son) ) {
2047 E( son -> execute(S, c, resolvingGlobals) );
2051 proc -> vars -> startCall();
2053 E( proc -> execute(S, (Vertex*) NULL, newc, resolvingGlobals ));
2055 // newc has been deleted by now
2057 proc -> vars -> endCall();
2062 a = NZ( atts.find(XSLA_SELECT) );
2063 Expression temp(*this);
2064 E( NZ( a -> expr ) -> eval(S, temp, c, resolvingGlobals) );
2065 // set output escaping
2066 Attribute *disableEsc = atts.find(XSLA_DISABLE_OUTPUT_ESC);
2067 if (disableEsc && disableEsc -> cont == (const char*)"yes")
2068 E( proc -> outputter() -> eventDisableEscapingForNext(S) );
2071 E( temp.tostring(S, cont) );
2072 E( proc -> outputter() -> eventData(S, cont) );
2077 a = NZ( atts.find(XSLA_SELECT) );
2078 Expression temp(*this);
2079 E( NZ( a -> expr ) -> eval(S, temp, c, resolvingGlobals) );
2080 if (temp.type == EX_NODESET)
2082 const Context& ctxt = temp.tonodesetRef();
2083 int k, kLimit = ctxt.getSize();
2085 for (k = 0; k < kLimit; k++)
2086 // assuming here the context holds physical vertices
2087 //E( toPhysical(ctxt[k]) -> copy(S, *(proc -> outputter())) );
2088 E( S.dom().copyNode(S, ctxt[k], *(proc -> outputter())) );
2093 E( temp.tostring(S, cont) );
2094 E( proc -> outputter() -> eventData(S, cont) );
2099 NodeHandle curr = c -> current();
2100 E( S.dom().startCopy(S, curr, *(proc -> outputter())) );
2101 //E( curr -> startCopy(S, *(proc -> outputter())) );
2102 //execute attribute sets
2103 E( executeAttributeSets(S, c, resolvingGlobals) );
2105 E( contents.execute(S, c, resolvingGlobals) );
2106 E( S.dom().endCopy(S, curr, *(proc -> outputter())) );
2107 //E( curr -> endCopy(S, *(proc -> outputter())) );
2111 a = NZ( atts.find(XSLA_SELECT) );
2114 E( NZ( a -> expr ) -> createContext(S, newc));
2116 if (!(*newc).isVoid() && contents.number())
2118 // *** SORT HERE ***
2119 SortDefList sortDefs;
2120 makeSortDefs(S, sortDefs, c);
2121 if (sortDefs.number())
2122 E( (*newc).sort(S, this, &sortDefs) );
2123 sortDefs.freeall(FALSE);
2125 E( proc -> execute(S, contents, newc, resolvingGlobals) );
2126 // proc disposes of the new context
2131 newc.del(); // done automatically
2135 case XSL_CALL_TEMPLATE:
2138 a = NZ( atts.find(XSLA_NAME) );
2139 XSLElement *thatrule;
2140 E( setLogical(S, q, a -> cont, FALSE) );
2141 if (!(thatrule = getOwner().findRuleByName(q)))
2143 Err1(S, E1_RULE_NOT_FOUND, (char*)getOwner().expand(q.getLocal()));
2146 // proc -> vars -> rmPrebindings();
2147 //process with-param
2148 E( contents.execute(S, c, resolvingGlobals) );
2149 //execute the other rule
2150 // proc -> vars -> startLevel();
2151 E( thatrule -> execute(S, c, resolvingGlobals) );
2152 proc -> vars -> rmPrebindings();
2153 // proc -> vars -> endLevel();
2158 GP( Expression ) expr = new Expression(*this);
2159 if (contents.isEmpty())
2161 (*expr).setAtom((const char*)"");
2165 proc -> vars -> startNested();
2166 TreeConstructer *newTC;
2167 E( proc -> pushTreeConstructer(S, newTC, (*expr).setFragment(),
2168 SAXOUTPUT_INT_PHYSICAL) );
2169 E( contents.execute(S, c, resolvingGlobals) );
2170 E( proc -> outputter() -> eventEndOutput(S) );
2171 E( proc -> popTreeConstructer(S, newTC) );
2172 proc -> vars -> endNested();
2174 GP( Expression ) temp = new Expression(*this);
2175 E( (*expr).eval(S, *temp,c, resolvingGlobals) );
2176 (*temp).pTree = (*expr).pTree;
2177 (*expr).pTree = NULL;
2178 a = atts.find(XSLA_TERMINATE);
2180 (*temp).tostring(S, tempStr);
2181 if (a && a -> cont == (const char*) "yes")
2183 Err1(S, E1_XSL_MESSAGE_TERM, tempStr);
2187 Warn1(S, W1_XSL_MESSAGE_NOTERM, tempStr);
2190 delete NZ(expr); GP: automatic
2195 // this is only executed for non-toplevel vars/params
2196 // (see case XSL_STYLESHEET)
2198 case XSL_WITH_PARAM:
2203 GP( Expression ) expr = NULL;
2205 // there must be a 'name' attribute
2206 a = NZ(atts.find(XSLA_NAME));
2207 // stick the name into q referring to this element's namespace decl's
2208 E( setLogical(S, q, a -> cont, FALSE) );
2210 // if there's a 'select', use the expression it gives
2211 a = atts.find(XSLA_SELECT);
2213 expr.assign(NZ(a -> expr));
2215 // otherwise, construct a new expression; it may be an empty string
2216 // if this element has void content, or a result tree fragment otherwise
2219 expr = new Expression(*this);
2220 if (contents.isEmpty())
2221 (*expr).setAtom((const char*)"");
2222 else // result tree fragment
2224 // starting a nesting will make the current prebindings
2226 // don't do it if we are resolving globals
2228 proc -> pushInBinding(TRUE);
2230 if (!resolvingGlobals)
2231 proc -> vars -> startNested();
2232 TreeConstructer *newTC;
2233 E( proc -> pushTreeConstructer(S, newTC, (*expr).setFragment(),
2234 SAXOUTPUT_INT_PHYSICAL) );
2235 // execute the inside to create the fragment
2236 E( contents.execute(S, c, resolvingGlobals) );
2237 E( proc -> outputter() -> eventEndOutput(S) );
2238 E( proc -> popTreeConstructer(S, newTC) );
2240 // end the shadowing of preexisting bindings
2241 if (!resolvingGlobals)
2242 proc -> vars -> endNested();
2244 proc -> popInBinding();
2248 // evaluate the expression
2249 GP( Expression ) temp = new Expression(*this);
2250 E( (*expr).eval(S, *temp, c, resolvingGlobals) );
2251 (*temp).pTree = (*expr).pTree;
2252 (*expr).pTree = NULL;
2254 // expr is automatically deallocated if newly constructed
2256 // add the new binding
2261 E( proc -> vars -> addBinding(S, q, temp, FALSE) );
2263 case XSL_WITH_PARAM:
2265 E( proc -> vars -> addPrebinding(S, q, temp) );
2269 E( proc -> vars -> addBinding(S, q, temp, TRUE) );
2272 temp.keep(); // deleted when removing the binding
2277 *name = atts.find(XSLA_NAME),
2278 *match = atts.find(XSLA_MATCH),
2279 *use = atts.find(XSLA_USE);
2280 assert(name && match && use && match -> expr && use -> expr);
2283 E( setLogical(S, q, NZ(name) -> cont, FALSE) );
2284 getOwner().expandQ(q, ename);
2285 E( proc -> addKey(S, ename, *(match -> expr), *(use -> expr)) );
2287 case XSL_DECIMAL_FORMAT:
2289 Attribute *name = atts.find(XSLA_NAME);
2292 E( setLogical(S, q, name -> cont, FALSE) );
2294 getOwner().expandQ(q, ename);
2295 DecimalFormat *decFormat;
2296 E( proc -> decimals().add(S, ename, decFormat) );
2297 for (int k = 0; k < atts.number(); k++)
2299 if (toA(atts[k]) -> op != XSLA_NAME)
2300 E( decFormat -> setItem(S, toA(atts[k]) -> op, toA(atts[k]) -> cont) );
2304 #define evalToStr(ATT, VAR) \
2305 { if (NULL != (e = getAttExpr(ATT)))\
2306 { E( e -> eval(S, evaluated, c, resolvingGlobals) );\
2307 E( evaluated.tostring(S, VAR) ); }}
2311 // auxiliary functions are in numbering.h
2315 Expression *e = getAttExpr(XSLA_VALUE),
2316 evaluated(*this, EXF_ATOM);
2319 E( e -> eval(S, evaluated, c, resolvingGlobals) );
2320 theList.append(evaluated.tonumber(S).round());
2324 NumberingLevel level = NUM_SINGLE;
2326 if (NULL != (a = atts.find(XSLA_LEVEL)))
2328 if (a -> cont == "multiple")
2329 level = NUM_MULTIPLE;
2330 else if (a -> cont == "any")
2332 else if (!(a -> cont == "single"))
2333 Err1(S, E1_NUMBER_LEVEL, a -> cont);
2335 E( xslNumberCount(S, level,
2336 getAttExpr(XSLA_COUNT),
2337 getAttExpr(XSLA_FROM),
2344 int groupingSize = 0;
2346 evalToStr(XSLA_FORMAT, format); // defined above case XSL_NUMBER
2347 evalToStr(XSLA_LANG, lang);
2349 // get @letter-value
2350 NumberingLetterValue letterValue = NUM_ALPHABETIC;
2351 if (NULL != (e = getAttExpr(XSLA_LETTER_VALUE)))
2353 E( e -> eval(S, evaluated, c, resolvingGlobals) );
2354 E( evaluated.tostring(S, letterValueStr) );
2355 if (letterValueStr == "traditional")
2356 letterValue = NUM_TRADITIONAL;
2357 else if (!(letterValueStr == "alphabetic"))
2358 Err1(S, E1_NUMBER_LETTER_VALUE, letterValueStr);
2361 // get @grouping-size
2362 if (NULL != (e = getAttExpr(XSLA_GROUPING_SIZE)))
2364 E( e -> eval(S, evaluated, c, resolvingGlobals) );
2365 groupingSize = evaluated.tonumber(S).round();
2368 // get @grouping-separator
2370 if (NULL != (eSep = getAttExpr(XSLA_GROUPING_SEPARATOR)))
2372 E( eSep -> eval(S, evaluated, c, resolvingGlobals) );
2373 E( evaluated.tostring(S, groupingSep) );
2378 if (!e || !eSep || groupingSize <= 0 || utf8StrLength(groupingSep) != 1)
2380 Warn(S, W_NUMBER_GROUPING);
2382 groupingSep.empty();
2386 E( xslNumberFormat(S, theList, format,
2387 lang, letterValue, groupingSep, groupingSize, theString) );
2389 E( proc -> outputter() -> eventData(S, theString) );
2392 case XSL_NAMESPACE_ALIAS:
2393 // these were processed during parse
2396 // processed by parent
2398 case XSL_ATTRIBUTE_SET:
2399 //processed during parse
2401 // unsupported instructions that are not considered harmful
2402 case XSL_STRIP_SPACE:
2403 case XSL_PRESERVE_SPACE:
2404 //processed during parse
2405 //Warn1(S, W1_UNSUPP_XSL, xslOpNames[op]);
2408 Err1(S, E1_UNSUPP_XSL, xslOpNames[op]);
2411 //remove the variable bindings that occured inside this element
2412 if ((op != XSL_TEMPLATE) && (op != XSL_TRANSFORM) && (op != XSL_STYLESHEET) &&
2413 (op != XSL_FOR_EACH) && !didNotExecute)
2418 Expression* XSLElement::getAttExpr(XSL_ATT code)
2420 Attribute *a = atts.find(code);
2421 return a ? (a -> expr) : NULL;
2424 int XSLElement::strip()
2426 if (op != XSL_TEXT && !preserveSpace)
2427 return /* defs.strip() + */ contents.strip();
2431 /*................................................................
2433 returns the index of given attribute in the attribute table
2435 ................................................................*/
2437 int findAttNdx(InstrTableItem &iitem, Attribute *a)
2439 for (int i = 0; i < iitem.maxAtts; i++)
2440 if (iitem.att[i].attCode == a -> op) return i;
2444 /*================================================================
2446 called when all attributes have been parsed in. Returns FALSE
2447 iff they are OK. Return value of TRUE means that the end tag handler
2449 ================================================================*/
2451 eFlag XSLElement::checkAtts(Sit S)
2453 InstrTableItem &instrData = instrTable[op];
2454 assert(instrData.op == op);
2459 for (int i = 0; i < atts.number(); i++)
2461 // need to use a temporary variable
2462 // to get around Solaris template problem
2463 Vertex * pTemp = atts[i];
2464 a = cast(Attribute*, pTemp);
2465 if (((attNdx = findAttNdx(instrData,a)) == -1) &&
2466 a -> name.getUri() == UNDEF_PHRASE)
2467 // FIXME: issue a warning when ignoring an att??
2470 owner.expandQStr(a -> name, fullName);
2471 Err1(S, ET_BAD_ATTR, fullName);
2473 if (instrData.att[attNdx].required)
2475 if (instrData.att[attNdx].exprType != EX_NONE)
2477 E( a -> buildExpr(S,
2478 instrData.att[attNdx].avtemplate,
2479 instrData.att[attNdx].exprType) );
2480 if (op == XSL_TEMPLATE && a->op == XSLA_MATCH)
2482 //must not contain variable ref
2483 if (a->expr && a->expr->containsFunctor(EXF_VAR))
2484 Err(S, E_VAR_IN_MATCH);
2488 if (reqCount < instrData.reqAtts)
2489 Err(S, ET_REQ_ATTR);
2493 //................................................................
2495 void XSLElement::checkExtraChildren(int& k)
2500 for (k = 0; k < contents.number(); k++)
2503 if (!isXSLElement(w)) return;
2504 hisop = toX(w) -> op;
2507 case XSL_APPLY_TEMPLATES:
2508 if ((hisop != XSL_SORT) && (hisop != XSL_WITH_PARAM)) return;
2510 case XSL_ATTRIBUTE_SET:
2511 if (hisop != XSL_ATTRIBUTE) return;
2513 case XSL_CALL_TEMPLATE:
2514 if (hisop != XSL_WITH_PARAM) return;
2521 if (status <= 1) status = 1;
2526 if (status == 1) status = 2;
2533 if (hisop != XSL_SORT) return;
2535 case XSL_STYLESHEET:
2537 if (hisop != XSL_WITH_PARAM) return;
2540 if (hisop != XSL_PARAM) return;
2548 eFlag XSLElement::checkToplevel(Sit S)
2550 //if we're nested in top level foreign node, all is ok
2551 if (vt & VT_TOP_FOREIGN) return OK;
2553 if (!(instrTable[op].flags & ELEM_INSTR) &&
2554 !(instrTable[op].flags & ELEM_EXTRA) &&
2556 !(instrTable[toX(parent) -> op].flags & ELEM_CONT_TOPLEVEL)))
2557 Err1(S, E1_ELEM_TOPLEVEL, xslOpNames[op]);
2561 eFlag XSLElement::checkChildren(Sit S)
2563 InstrTableItem &iData = instrTable[op];
2564 assert(iData.op == op);
2566 if (!(iData.flags & ELEM_CONT) && contents.number())
2567 Err1(S, E_ELEM_MUST_EMPTY, xslOpNames[op]);
2570 if (iData.flags & ELEM_CONT_EXTRA)
2571 checkExtraChildren(firstAfter);
2573 for (int k = firstAfter; k < contents.number(); k++)
2575 Vertex *w = contents[k];
2577 if (isElement(w) && (toE(w)->getName().getPrefix() != UNDEF_PHRASE) &&
2578 (iData.flags & ELEM_CONT_EXTENSION))
2583 if (isElement(w) && (iData.flags & ELEM_CONT_PCDATA)) {
2584 Err1(S, E_ELEM_MUST_BE_PCDATA, xslOpNames[op]);
2587 if (isText(w) || (isElement(w) && !isXSLElement(w)))
2589 if (!(iData.flags & (ELEM_CONT_INSTR | ELEM_CONT_PCDATA)))
2590 Err1(S, E_ELEM_CONT_TEXT_OR_LRE, xslOpNames[op]);
2594 if (isXSLElement(w))
2596 int hisflags = instrTable[toX(w) -> op].flags;
2597 if (!(((hisflags & ELEM_TOPLEVEL) && (iData.flags & ELEM_CONT_TOPLEVEL)) ||
2598 ((hisflags & ELEM_INSTR) && (iData.flags & ELEM_CONT_INSTR))))
2599 Err2(S, E_ELEM_CONTAINS_ELEM, xslOpNames[op], xslOpNames[toX(w) -> op]);
2602 Err1(S, E_BAD_ELEM_CONTENT, xslOpNames[op]);
2609 eFlag XSLElement::make1SortDef(Sit S, SortDef *&def, Context *c)
2613 assert(op == XSL_SORT);
2615 GP( SortDef ) newDef = new SortDef;
2617 Attribute *a = atts.find(XSLA_SELECT);
2619 (*newDef).sortExpr = a -> expr;
2621 a = atts.find(XSLA_LANG);
2624 E( a -> value(S, temp, c));
2625 (*newDef).lang = temp;
2629 // lang is system-dependent!!! How about setting ""?
2630 (*newDef).lang = "en";
2633 a = atts.find(XSLA_DATA_TYPE);
2636 E( a -> value(S, temp, c) );
2637 if (temp == (const char*) "number")
2638 (*newDef).asText = FALSE;
2640 if (!(temp == (const char*) "text"))
2641 Warn1(S, W1_SORT_DATA_TYPE, temp);
2644 a = atts.find(XSLA_ORDER);
2647 E( a -> value(S, temp, c) );
2648 if (temp == (const char*) "descending")
2649 (*newDef).ascend = FALSE;
2650 else if (!(temp == (const char*) "ascending"))
2651 Warn1(S, W1_SORT_ORDER, temp);
2654 a = atts.find(XSLA_CASE_ORDER);
2657 E( a -> value(S, temp, c) );
2658 if (temp == (const char*) "lower-first")
2659 (*newDef).upper1st = FALSE;
2662 if (!(temp == (const char*) "upper-first"))
2663 Warn1(S, W1_SORT_CASE_ORDER, temp);
2664 // get upper1st as system default!!
2665 (*newDef).upper1st = TRUE;
2668 def = newDef.keep();
2672 eFlag XSLElement::makeSortDefs(Sit S, SortDefList &sortDefs, Context *c)
2674 assert(op == XSL_APPLY_TEMPLATES || op == XSL_FOR_EACH);
2677 for (int i = 0; i < contents.number(); i++)
2679 child = contents[i];
2680 if (!isXSLElement(child)) break;
2681 if (toX(child) -> op == XSL_SORT)
2683 // *** make the single sort def
2685 E( toX(child) -> make1SortDef(S, newDef, c) );
2686 sortDefs.append(newDef);
2687 # if !defined(SAB_WCS_COLLATE)
2688 // warn that string sorting may be incorrect -
2690 if (newDef -> asText)
2691 Warn(S, W_NO_WCSXFRM);
2695 else if (toX(child) -> op != XSL_WITH_PARAM) break;
2700 /****************************************
2702 ****************************************/
2703 const char* extNSUri[] = {
2704 "http://exslt.org/functions",
2705 "http://www.exslt.org/functions",
2706 "http://exslt.org/common",
2710 const char* exsltElementsFunctions[] = {
2715 const char* exsltElementsCommon[] = {
2720 ExtensionElement::ExtensionElement(Tree& owner_, QName& aqname)
2722 Element(owner_, aqname, VT_EXT_ELEMENT_WF)
2724 extns = EXTNS_UNKNOWN;
2726 lookupExt(owner, aqname, extns, op);
2730 eFlag ExtensionElement::executeEXSLTScript(Sit S, Context *c,
2731 Bool resolvingGlobals)
2733 #ifdef SABLOT_DEBUGGER
2734 if (debugger) E( debugger -> breakOnElement(S, this, c) );
2739 //attName.setUri(getName().getUri());
2740 attName.setLocal(owner.unexpand("language"));
2741 Attribute *a = NZ( atts.find(attName) );
2744 E( setLogical(S, lang, a -> cont, false) );
2747 getOwner().expandQ(lang, elang);
2749 if (lang.getUri() == UNDEF_PHRASE || elang.getUri() == extNSUri[0])
2751 if (! (elang.getLocal() == (const char*)"javascript") &&
2752 ! (elang.getLocal() == (const char*)"ecmascript"))
2759 //if (!(a -> cont == (const char*) "javascript") &&
2760 // !(a -> cont == (const char*) "ecmascript"))
2764 attName.setLocal(owner.unexpand("implements-prefix"));
2765 a = NZ( atts.find(attName) );
2767 Phrase uri = owner.unexpand(a -> cont);
2768 E( namespaces.resolve(S, uri, TRUE) );
2769 Str suri = owner.expand(uri);
2770 //check uri validity!!!
2775 attName.setLocal(owner.unexpand("src"));
2776 a = atts.find(attName);
2780 StrStrList &args = S.getProcessor() -> getArgList();
2782 const Str &base = S.findBaseURI(getSubtreeInfo() -> getBaseURI());
2784 makeAbsoluteURI(S, a -> cont, base, absolute);
2786 eFlag status = src.open(S, absolute, DLMODE_READ, &args);
2792 while ((read = src.get(S, buff, 1024)))
2794 script.nadd(buff, read);
2805 for (int i = 0; i < contents.number(); i++)
2807 Vertex *v = contents[i];
2810 script = script + toText(v) -> cont;
2814 E( NZ( S.getProcessor() ) -> evaluateJavaScript(S, suri, script) );
2819 const char* _exsltDocAtts[] = {
2822 "omit-xml-declaration",
2831 XSL_ATT _exsltDocMapping[] = {
2836 XSLA_DOCTYPE_PUBLIC,
2837 XSLA_DOCTYPE_SYSTEM,
2843 XSL_ATT _lookupEXSLTDocumentAttr(const char* name)
2845 int idx = lookup(name, _exsltDocAtts);
2846 return _exsltDocMapping[idx];
2849 eFlag ExtensionElement::exsltDocGetOutputterDef(Sit S, Context *c,
2850 OutputDefinition &def)
2852 int i, attsNumber = atts.number();
2854 for (i = 0; i < attsNumber; i++)
2856 theAtt = toA(atts[i]);
2857 Str attName = getOwner().expand(theAtt -> getName().getLocal());
2858 Str attUri = getOwner().expand(theAtt -> getName().getUri());
2860 //skip xslt attributes
2861 if ( attUri == theXSLTNamespace )
2864 if (attName == (const char*) "method")
2869 theAtt -> value(S, val, c);
2870 E( setLogical(S, q, val, FALSE) );
2871 getOwner().expandQ(q, eq);
2872 E( def.setItemEQName(S, XSLA_METHOD, eq, theAtt, 0) );
2874 else if (attName == (const char*) "cdata-section-elements")
2880 theAtt -> value(S, val, c);
2881 char *p = (char*)val;
2884 someRemains = getWhDelimString(p, listPart);
2887 E( setLogical(S, q, listPart, TRUE) );
2889 getOwner().expandQ(q, expanded);
2890 E( def.setItemEQName(S, XSLA_CDATA_SECT_ELEMS,
2891 expanded, theAtt, 0) );
2894 while (someRemains);
2896 else if ( !(attName == (const char*) "href") )
2899 theAtt -> value(S, val, c);
2900 XSL_ATT attType = _lookupEXSLTDocumentAttr(attName);
2901 if (attType == XSLA_NONE)
2902 Err1(S, ET_BAD_ATTR, (char*)attName);
2903 E( def.setItemStr(S, attType, val, theAtt, 0) );
2910 eFlag ExtensionElement::executeEXSLTDocument(Sit S, Context *c,
2911 Bool resolvingGlobals)
2913 Processor *proc = NZ( S.getProcessor() );
2917 attName.setLocal(owner.unexpand("href"));
2918 Attribute *a = NZ( atts.find(attName) );
2921 E( a -> value(S, href, c) );
2923 GP(OutputDefinition) def = new OutputDefinition();
2924 E( exsltDocGetOutputterDef(S, c, *def) );
2926 OutputDocument *doc;
2927 E( proc -> createOutputDocument(S, href, doc, def.keep()) );
2928 //we do not need to keep the definition, since document
2929 //initialized the outputter with it (I hope)
2931 Bool handleOutputter = !proc -> isInBinding();
2933 if (handleOutputter)
2935 S.message(MT_LOG, L2_SUBDOC_STARTED, href, "output");
2936 E( proc -> startDocument(S, doc) );
2940 S.message(MT_LOG, L2_SUBDOC_STARTED, href, "variable");
2941 E( proc -> outputter() -> setDocumentForLevel(S, doc) );
2944 E( contents.execute(S, c, resolvingGlobals) );
2946 if (handleOutputter)
2948 E( proc -> finishDocument(S, doc, TRUE) );
2954 eFlag ExtensionElement::execute(Sit S, Context *c, Bool resolvingGlobals)
2957 case EXTE_EXSLT_SCRIPT:
2959 E( executeEXSLTScript(S, c, resolvingGlobals) );
2961 assert(!"JSExtension not build");
2964 case EXTE_EXSLT_DOCUMENT:
2965 E( executeEXSLTDocument(S, c, resolvingGlobals) );
2970 Bool hasSome = FALSE;
2971 executeFallback(S, c, hasSome, resolvingGlobals);
2974 Str name = owner.expand(getName().getPrefix());
2976 name = name + owner.expand(getName().getLocal());
2977 Err1(S, E_UNSUPPORTED_EXELEMENT, (char*)name);
2986 eFlag ExtensionElement::checkChildren(Sit S)
2989 case EXTNS_EXSLT_FUNCTIONS:
2990 case EXTNS_EXSLT_FUNCTIONS_2:
2992 int num = contents.number();
2993 for (int i = 0; i < num; i++)
2995 Vertex *v = contents[i];
2997 (! isXSLElement(v) || !(toX(v) -> op == XSL_FALLBACK)) )
2999 Err(S, E_BAD_ELEM_CONTENT);
3008 eFlag ExtensionElement::checkHasAttr(Sit S, const char *name)
3011 attName.setLocal(owner.unexpand(name));
3012 Attribute *a = atts.find(attName);
3013 if (!a) Err1(S, E_ATTR_MISSING, name);
3017 eFlag ExtensionElement::checkAtts(Sit S)
3020 case EXTE_EXSLT_SCRIPT:
3022 E( checkHasAttr(S, "implements-prefix") );
3023 E( checkHasAttr(S, "language") );
3025 case EXTE_EXSLT_DOCUMENT:
3027 E( checkHasAttr(S, "href") );
3028 //all attributes are value templates
3029 int num = atts.number();
3030 for (int i = 0; i < num; i++)
3031 E( toA(atts[i]) -> buildExpr(S, TRUE, EX_NONE) );
3037 void ExtensionElement::lookupExt(Tree &tree, QName &name,
3038 ExtNamespace &extns_, ExtElement &op_)
3040 Str myns = tree.expand(name.getUri());
3041 Str mylocal = tree.expand(name.getLocal());
3042 extns_ = (ExtNamespace) lookup(myns, extNSUri);
3044 case EXTNS_EXSLT_FUNCTIONS:
3045 case EXTNS_EXSLT_FUNCTIONS_2:
3047 int i = lookup(mylocal, exsltElementsFunctions);
3048 if ( exsltElementsFunctions[i] ) {
3049 op_ = (ExtElement) (i + (int)EXTE_EXSLT_FUNCTIONS);
3054 case EXTNS_EXSLT_COMMON:
3056 int i = lookup(mylocal, exsltElementsCommon);
3057 if ( exsltElementsCommon[i] ) {
3058 op_ = (ExtElement) (i + (int)EXTE_EXSLT_COMMON);
3068 //now we have to check, whether the element is really supported
3070 if (op_ == EXTE_EXSLT_SCRIPT) op_ = EXTE_UNKNOWN;
3074 Bool ExtensionElement::elementAvailable(Tree &t, QName &name)
3078 lookupExt(t, name, ns, op);
3080 if (op == EXTE_EXSLT_SCRIPT) op = EXTE_UNKNOWN;
3082 return op != EXTE_UNKNOWN;