/** \fn memo_xsl **/ inline xsp_t memo_xsl(Trie* trie, unsigned char *xslfile){ debug("xsp_t memo_xsl(Trie* trie, unsigned char *xslfile)"); xsp_t xsl = (xsp_t)trie_lookup(trie, (char*)xslfile); if(NULL == xsl) { xsl = parse_xslt((const xc_t*) xslfile); trie_insert(trie, (char*)xslfile, xsl); } return xsl; }
/** \fn try_memo_xsl **/ inline xsp_t try_memo_xsl(Trie* trie, unsigned char *xslfile, int use_memo){ debug("xsp_t memo_xsl(Trie* trie, unsigned char *xslfile, int use_memo)"); xsp_t xsl = NULL; /*! Если нам нужна высокая эффективность, то мы кешируем шаблоны. Но если нам нужно удобство разработки мы этого не делаем. */ if(use_memo) xsl = memo_xsl(trie, xslfile); else xsl = parse_xslt((const xc_t*) xslfile); return xsl; }
int parse_xslt(elcgen *gen, xmlNodePtr parent, expression *pnode) { xmlNodePtr n; int r = 1; expression **cptr = &pnode->r.children; for (n = parent->children; n && r; n = n->next) { expression *newnode = NULL; if (ignore_node(n)) continue; if (XML_ELEMENT_NODE == n->type) { if (n->ns && !xmlStrcmp(n->ns->href,XSLT_NS)) { if (!xmlStrcmp(n->name,"output")) { newnode = new_xsltnode(n,XSLT_OUTPUT); } else if (!xmlStrcmp(n->name,"strip-space")) { newnode = new_xsltnode(n,XSLT_STRIP_SPACE); } else if (!xmlStrcmp(n->name,"function")) { newnode = new_xsltnode(n,XSLT_FUNCTION); r = r && parse_name(gen,n,newnode,1); } else if (!xmlStrcmp(n->name,"template")) { newnode = new_xsltnode(n,XSLT_TEMPLATE); newnode->orig = xmlGetProp(n,"match"); r = r && parse_expr_attr(gen,n,"match",&newnode->r.left,0,newnode); r = r && parse_name(gen,n,newnode,0); } else if (!xmlStrcmp(n->name,"param")) { newnode = new_xsltnode(n,XSLT_PARAM); r = r && parse_name(gen,n,newnode,1); } else if (!xmlStrcmp(n->name,"when")) { newnode = new_xsltnode(n,XSLT_WHEN); newnode->orig = xmlGetProp(n,"test"); r = r && parse_expr_attr(gen,n,"test",&newnode->r.left,1,newnode); } else if (!xmlStrcmp(n->name,"otherwise")) { newnode = new_xsltnode(n,XSLT_OTHERWISE); } else if (!xmlStrcmp(n->name,"variable")) { newnode = new_xsltnode(n,XSLT_VARIABLE); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,0,newnode); r = r && parse_name(gen,n,newnode,1); } else if (!xmlStrcmp(n->name,"sequence")) { newnode = new_xsltnode(n,XSLT_SEQUENCE); newnode->orig = xmlGetProp(n,"select"); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,1,newnode); } else if (!xmlStrcmp(n->name,"value-of")) { newnode = new_xsltnode(n,XSLT_VALUE_OF); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,0,newnode); } else if (!xmlStrcmp(n->name,"text")) { char *str = xmlNodeListGetString(gen->parse_doc,n->children,1); if (!strncmp(str,"#S",2) && gen->ispattern) { newnode = new_xsltnode(n,XSLT_DSVAR_TEXTINSTR); newnode->str = strdup((char*)str+1); free(str); } else { newnode = new_xsltnode(n,XSLT_TEXT); newnode->str = str; } } else if (!xmlStrcmp(n->name,"for-each")) { newnode = new_xsltnode(n,XSLT_FOR_EACH); newnode->orig = xmlGetProp(n,"select"); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,1,newnode); } else if (!xmlStrcmp(n->name,"if")) { newnode = new_xsltnode(n,XSLT_IF); newnode->orig = xmlGetProp(n,"test"); r = r && parse_expr_attr(gen,n,"test",&newnode->r.left,1,newnode); } else if (!xmlStrcmp(n->name,"choose")) { newnode = new_xsltnode(n,XSLT_CHOOSE); } else if (!xmlStrcmp(n->name,"element")) { newnode = new_xsltnode(n,XSLT_ELEMENT); newnode->orig = xmlGetProp(n,"name"); r = r && parse_avt(gen,n,"name",&newnode->r.name_avt,1,newnode); r = r && parse_avt(gen,n,"namespace",&newnode->r.namespace_avt,0,newnode); } else if (!xmlStrcmp(n->name,"attribute")) { newnode = new_xsltnode(n,XSLT_ATTRIBUTE); newnode->orig = xmlGetProp(n,"name"); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,0,newnode); r = r && parse_avt(gen,n,"name",&newnode->r.name_avt,1,newnode); } else if (!xmlStrcmp(n->name,"namespace")) { newnode = new_xsltnode(n,XSLT_NAMESPACE); newnode->orig = xmlGetProp(n,"name"); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,0,newnode); r = r && parse_avt(gen,n,"name",&newnode->r.name_avt,1,newnode); } else if (!xmlStrcmp(n->name,"apply-templates")) { newnode = new_xsltnode(n,XSLT_APPLY_TEMPLATES); newnode->orig = xmlGetProp(n,"select"); r = r && parse_expr_attr(gen,n,"select",&newnode->r.left,0,newnode); } else if (!strncmp((char*)n->name,"_Y",2) && gen->ispattern) { newnode = new_xsltnode(n,XSLT_DSVAR_LITELEM); /* newnode->str = strdup((char*)n->name+1); */ newnode->str = strdup("Y::"); /* FIXME: hack */ } else { r = gen_error(gen,"Unsupported XSLT instruction: %s",n->name); } } else { newnode = new_xsltnode(n,XSLT_LITERAL_RESULT_ELEMENT); newnode->qn.uri = n->ns ? strdup((char*)n->ns->href) : strdup(""); newnode->qn.prefix = (n->ns && n->ns->prefix) ? strdup((char*)n->ns->prefix) : strdup(""); newnode->qn.localpart = strdup((char*)n->name); r = r && parse_attributes(gen,n,newnode); } } else if (XML_TEXT_NODE == n->type) { if (!strncmp((char*)n->content,"#I",2) && gen->ispattern) { newnode = new_xsltnode(n,XSLT_DSVAR_INSTRUCTION); newnode->str = strdup((char*)n->content+1); } else if (!strncmp((char*)n->content,"#S",2) && gen->ispattern) { newnode = new_xsltnode(n,XSLT_DSVAR_TEXT); newnode->str = strdup((char*)n->content+1); } else { newnode = new_xsltnode(n,XSLT_LITERAL_TEXT_NODE); newnode->str = strdup((char*)n->content); } } if (newnode) { *cptr = newnode; cptr = &newnode->next; if ((XSLT_TEXT != newnode->type) && (XSLT_DSVAR_TEXTINSTR != newnode->type)) { if (!parse_xslt(gen,n,newnode)) return 0; } } } return r; }