XDocument* XParser::Parse(const char* szPath, bool keep_blank/*=false*/) { if(szPath==NULL) return NULL; xmlKeepBlanksDefault(keep_blank?1:0); xmlDoValidityCheckingDefaultValue =0; xmlParserCtxtPtr pxParseCtxt = NULL; pxParseCtxt = xmlCreateFileParserCtxt(szPath); if(pxParseCtxt==NULL) { return NULL; } if(pxParseCtxt->directory == NULL) { char* directory = xmlParserGetDirectory(szPath); pxParseCtxt->directory = (char*)xmlStrdup((xmlChar*)directory); } if(!ParseContext(pxParseCtxt)) { xmlFreeParserCtxt(pxParseCtxt); return NULL; } XDocument* pagXmlDoc = NULL; pagXmlDoc = new XDocument(pxParseCtxt->myDoc); xmlFreeParserCtxt(pxParseCtxt); return pagXmlDoc; }
/* Taken from libxml2, xmlSAXParseMemoryWithData */ xmlDocPtr mxslt_doc_xml_load_entity(mxslt_doc_t * document, char * localfile) { xmlParserCtxtPtr ctx; xmlParserInputPtr input; xmlDocPtr retval; xmlChar * filename; mxslt_doc_debug_print(document, MXSLT_DBG_LIBXML | MXSLT_DBG_DEBUG | MXSLT_DBG_VERBOSE0, "load_entity/xmlCreateMemoryParserCtxt -- replacing entities: %08x\n", xmlSubstituteEntitiesDefaultValue); /* SNIPPET: This is a good mix&shake of * xmlCreateMemoryParserCtxt, xmlCreateFileParserCtxt */ ctx=xmlNewParserCtxt(); if(ctx == NULL) return NULL; #if LIBXML_VERSION >= 20600 xmlCtxtUseOptions(ctx, MXSLT_XSLT_OPTIONS); #endif /* Remember which document we are parsing * in this context */ /* ctx->_private=document; */ filename=xmlCanonicPath((xmlChar *)localfile); if(filename == NULL) { xmlFreeParserCtxt(ctx); return NULL; } input=xmlLoadExternalEntity((char *)filename, NULL, ctx); xmlFree(filename); if(input == NULL) { xmlFreeParserCtxt(ctx); return NULL; } inputPush(ctx, input); if(ctx->directory == NULL) ctx->directory=xmlParserGetDirectory(localfile); /* END SNIPPET */ /* MXSLT_DUMP_CTX(ctx); */ /* Parse document */ xmlParseDocument(ctx); if(ctx->wellFormed) retval=ctx->myDoc; else { retval=NULL; xmlFreeDoc(ctx->myDoc); ctx->myDoc=NULL; } xmlFreeParserCtxt(ctx); return retval; }
std::auto_ptr<document> dom_parser::parse_file(const std::string& file_name) { set_global_variables global_variables; // Create a libxml2 parser context for parsing the xml file. dom_parser_context_wrapper context( xmlCreateFileParserCtxt(file_name.c_str()) ); if (context.get() == 0) { std::string what = "fail to parse xml file " + file_name + ": " + "unable to create libxml2 parser context"; throw dom_error(what); } if (context.get()->directory == 0) { const xmlChar* dir = detail::to_xml_chars(xmlParserGetDirectory(file_name.c_str())); context.get()->directory = const_cast<char*>(detail::to_chars(xmlStrdup(dir))); } // Parse xml file under the constructed parser context. xmlDoc* px = parse_in_context(context.get()); assert(px != 0); return std::auto_ptr<document>(new document(px)); }
/* Taken from libxml2, xmlSAXParseMemoryWithData */ xmlDocPtr mxslt_doc_xml_parse(mxslt_doc_t * document, xmlParserInputBufferPtr buf, char * localfile) { xmlParserCtxtPtr ctx; xmlParserInputPtr input; xmlDocPtr retval; mxslt_doc_debug_print(document, MXSLT_DBG_LIBXML | MXSLT_DBG_DEBUG | MXSLT_DBG_VERBOSE0, "xml_parse/xmlCreateMemoryParserCtxt -- replacing entities: %08x\n", xmlSubstituteEntitiesDefaultValue); if(buf == NULL) return NULL; /* SNIPPET: This is a good mix&shake of * xmlCreateMemoryParserCtxt, xmlCreateFileParserCtxt */ ctx=xmlNewParserCtxt(); if(ctx == NULL) { xmlFreeParserInputBuffer(buf); return NULL; } #if LIBXML_VERSION >= 20600 xmlCtxtUseOptions(ctx, MXSLT_XSLT_OPTIONS); #endif /* Default are no longer changed... since 2.6.0 they * are completely ignored, leading to broken modxslt :|| */ if(ctx->sax) { ctx->sax->resolveEntity=mxslt_sax_resolve_entity; ctx->sax->processingInstruction=mxslt_sax_processing_instruction; } /* Remember which document we are parsing * in this context */ /* ctx->_private=document; */ input=xmlNewInputStream(ctx); if(input == NULL) { xmlFreeParserInputBuffer(buf); xmlFreeParserCtxt(ctx); return NULL; } input->filename=(char *)xmlCanonicPath((xmlChar *)localfile); if(input->filename == NULL) { xmlFreeParserCtxt(ctx); xmlFreeParserInputBuffer(buf); xmlFreeInputStream(input); return NULL; } input->buf=buf; #if LIBXML_VERSION < 20900 input->base=input->buf->buffer->content; input->cur=input->buf->buffer->content; input->end=&input->buf->buffer->content[input->buf->buffer->use]; #else /* With libxml2 2.9.0, the buffer struct can only be accessed through * methods. */ input->base=xmlBufContent(input->buf->buffer); input->cur=xmlBufContent(input->buf->buffer); input->end=xmlBufEnd(input->buf->buffer); #endif inputPush(ctx, input); if(ctx->directory == NULL) ctx->directory=xmlParserGetDirectory(localfile); /* END SNIPPET */ if(mxslt_doc_debug_level(document, MXSLT_DBG_LIBXML | MXSLT_DBG_DEBUG | MXSLT_DBG_VERBOSE2)) mxslt_doc_dump_ctx(ctx, document); /* Parse document */ xmlParseDocument(ctx); if(ctx->wellFormed) retval=ctx->myDoc; else { retval=NULL; xmlFreeDoc(ctx->myDoc); ctx->myDoc=NULL; } xmlFreeParserCtxt(ctx); /* xmlFreeParserInputBuffer(buf); */ return retval; }
/* This function replaces processingInstruction */ void mxslt_sax_processing_instruction(void * ctx, const xmlChar * target, const xmlChar * data) { xmlParserCtxtPtr ctxt=(xmlParserCtxtPtr)ctx; mxslt_doc_t * document=(mxslt_get_state()->document); mxslt_pi_style_t * style_pi; mxslt_pi_param_t * param_pi; mxslt_pi_base_t * base_pi; char * type = NULL, * tmp; xmlNodePtr pi; int status; /* WARNING: don't change this array! Look below! */ static const mxslt_attr_search_t xml_stylesheet[] = { { (xmlChar *)"href", mxslt_sizeof_str("href") }, { (xmlChar *)"media", mxslt_sizeof_str("media") }, { (xmlChar *)"type", mxslt_sizeof_str("type") } }; /* WARNING: don't change this array! Look below! */ static const mxslt_attr_search_t mxslt_param[] = { { (xmlChar *)"name", mxslt_sizeof_str("name") }, { (xmlChar *)"value", mxslt_sizeof_str("value") } }; /* WARNING: don't change this array! Look below! */ static const mxslt_attr_search_t mxslt_base[] = { { (xmlChar *)"value", mxslt_sizeof_str("value") } }; /* This array _must_ have the same number of elements * as the array xml_stylesheet */ char * xml_stylesheet_values[] = { NULL, NULL, NULL }; enum xml_stylesheet_types { t_href=0, t_media, t_type }; /* This array _must_ have the same number of elements * as the array mxslt_param */ char * mxslt_param_values[] = { NULL, NULL }; enum mxslt_param_types { t_name=0, t_select }; /* This array _must_ have the same number of elements * as the array mxslt_base */ char * mxslt_base_values[] = { NULL }; enum mxslt_base_types { t_value=0 }; mxslt_doc_debug_print(document, MXSLT_DBG_LIBXML, "processing instruction \"%s\", attributes |%s|\n", target, data); /* Ignore pi when we're parsing the stylesheet */ if(document->flags & MXSLT_STYLE) return; /* Create a new pi node */ pi=xmlNewPI(target, data); if(!pi) return; /* Check if target is a known pi */ switch(target[0]) { case 'x': if(!xmlStrEqual(target+1, (xmlChar *)"xml-stylesheet"+1)) break; /* Get href, type and media from attribute list */ status=mxslt_get_static_attr((char *)data, xml_stylesheet, xml_stylesheet_values, mxslt_sizeof_array(xml_stylesheet)); if(status != MXSLT_OK) { if(xml_stylesheet_values[0]) xfree(xml_stylesheet_values[0]); if(xml_stylesheet_values[1]) xfree(xml_stylesheet_values[1]); if(xml_stylesheet_values[2]) xfree(xml_stylesheet_values[2]); goto error; } if(xml_stylesheet_values[t_type] && xml_stylesheet_values[t_href]) { /* Decode type */ type=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)xml_stylesheet_values[t_type], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); /* Skip blanks before type */ for(tmp=type; MXSLT_IS_BLANK(*tmp); tmp++) ; /* compare type string */ if(!strncmp(tmp, "text/xml", mxslt_sizeof_str("text/xml")) || !strncmp(tmp, "text/xsl", mxslt_sizeof_str("text/xsl"))) { /* trailing spaces are allowed */ for(tmp+=mxslt_sizeof_str("text/x?l"); MXSLT_IS_BLANK(*tmp); tmp++) ; /* Check there's nothing else beside them */ if(*tmp != '\0') { xmlFree(type); break; } /* Type is ok, add parameter to processing * instruction */ style_pi=(mxslt_pi_style_t *)xmalloc(sizeof(mxslt_pi_style_t)); style_pi->type=MXSLT_PI_STDST; style_pi->ctype=type; style_pi->href=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)xml_stylesheet_values[t_href], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); if(xml_stylesheet_values[t_media]) style_pi->media=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)xml_stylesheet_values[t_media], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); else style_pi->media=NULL; /* tie up xmlNode and style_pi */ XML_LINK_PI(document, pi, style_pi); } else { mxslt_error(document, "warning - <xml-stylesheet type=\"... unknown: '%s'!\n", type); xmlFree(type); } } else { if(!xml_stylesheet_values[t_href]) mxslt_error(document, "warning - <xml-stylesheet href=\"... is missing, skipping PI!\n"); if(!xml_stylesheet_values[t_type]) mxslt_error(document, "warning - <xml-stylesheet type=\"... is missing, skipping PI!\n"); } if(xml_stylesheet_values[t_media]) xfree(xml_stylesheet_values[t_media]); if(xml_stylesheet_values[t_href]) xfree(xml_stylesheet_values[t_href]); if(xml_stylesheet_values[t_type]) xfree(xml_stylesheet_values[t_type]); break; case 'm': if(target[1] != 'o' || target[2] != 'd' || target[3] != 'x' || target[4] != 's' || target[5] != 'l' || target[6] != 't' || target[7] != '-') break; switch(target[8]) { case 'b': if(!xmlStrEqual(target+8, (xmlChar *)"modxslt-base"+8)) { mxslt_error(document, "warning - unknown modxslt PI: %s in %s\n", target, document->localfile); break; } /* Read modxslt-base */ status=mxslt_get_static_attr((char *)data, mxslt_base, mxslt_base_values, mxslt_sizeof_array(mxslt_base)); if(status != MXSLT_OK) { if(mxslt_base_values[0]) xfree(mxslt_base_values[0]); goto error; } /* Verify we got the base */ if(!mxslt_base_values[0]) { mxslt_error(document, "warning - <modxslt-base ... base=\" is missing, skipping PI\n", target, document->localfile); break; } /* Remember the pi we found */ base_pi=(mxslt_pi_base_t *)(xmalloc(sizeof(mxslt_pi_base_t))); base_pi->type=MXSLT_PI_UBASE; base_pi->file=(char *)xmlCanonicPath((xmlChar *)mxslt_base_values[0]); base_pi->directory=xmlParserGetDirectory(mxslt_base_values[0]); xfree(mxslt_base_values[0]); /* Switch base in the current context */ if(ctxt->input->filename) xmlFree((char *)ctxt->input->filename); if(ctxt->directory) xmlFree(ctxt->directory); /* Remember those information */ ctxt->input->filename=(char *)xmlStrdup((xmlChar *)base_pi->file); ctxt->directory=(char *)xmlStrdup((xmlChar *)base_pi->directory); /* tie up xmlNode and style_pi */ XML_LINK_PI(document, pi, base_pi); break; case 'p': if(!xmlStrEqual(target+8, (xmlChar *)"modxslt-param"+8)) { mxslt_error(document, "warning - unknown modxslt PI: %s in %s\n", target, document->localfile); break; } status=mxslt_get_static_attr((char *)data, mxslt_param, mxslt_param_values, mxslt_sizeof_array(mxslt_param)); if(status != MXSLT_OK) { if(mxslt_param_values[0]) xfree(mxslt_param_values[0]); if(mxslt_param_values[1]) xfree(mxslt_param_values[1]); goto error; } if(mxslt_param_values[t_name]) { /* Allocate and create pi */ param_pi=(mxslt_pi_param_t *)xmalloc(sizeof(mxslt_pi_param_t)); param_pi->type=MXSLT_PI_PARAM; param_pi->param=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)mxslt_param_values[t_name], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); param_pi->value=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)mxslt_param_values[t_select], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); /* Link pi to list of pis */ XML_LINK_PI(document, pi, param_pi); } else { mxslt_error(document, "warning - modxslt-param specified without ``name'' attribute in `%s'\n", document->localfile); } /* Free memory up */ if(mxslt_param_values[t_select]) xfree(mxslt_param_values[t_select]); if(mxslt_param_values[t_name]) xfree(mxslt_param_values[t_name]); break; case 's': if(!xmlStrEqual(target+8, (xmlChar *)"modxslt-stylesheet"+8)) { mxslt_error(document, "warning - unknown modxslt PI: %s in %s\n", target, document->localfile); break; } status=mxslt_get_static_attr((char *)data, xml_stylesheet, xml_stylesheet_values, mxslt_sizeof_array(xml_stylesheet)); if(status != MXSLT_OK) { if(xml_stylesheet_values[0]) xfree(xml_stylesheet_values[0]); if(xml_stylesheet_values[1]) xfree(xml_stylesheet_values[1]); if(xml_stylesheet_values[2]) xfree(xml_stylesheet_values[2]); goto error; } if(xml_stylesheet_values[t_type]) { /* Decode type */ type=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)xml_stylesheet_values[t_type], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); /* Skip blanks before type */ for(tmp=type; MXSLT_IS_BLANK(*tmp); tmp++) ; /* compare type string */ if(!strncmp(tmp, "text/xml", mxslt_sizeof_str("text/xml")) || !strncmp(tmp, "text/xsl", mxslt_sizeof_str("text/xsl"))) { /* trailing spaces are allowed */ for(tmp+=mxslt_sizeof_str("text/x?l"); MXSLT_IS_BLANK(*tmp); tmp++) ; /* Check there's nothing else beside them */ if(*tmp != '\0') { mxslt_error(document, "warning - <modxslt-stylesheet type=\"... trailing junk: '%s'!\n", type); xmlFree(type); break; } /* Type is ok, add parameter to processing * instruction */ style_pi=(mxslt_pi_style_t *)xmalloc(sizeof(mxslt_pi_style_t)); style_pi->type=MXSLT_PI_MODST; style_pi->ctype=type; if(xml_stylesheet_values[t_href]) style_pi->href=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)xml_stylesheet_values[t_href], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); else style_pi->href=NULL; if(xml_stylesheet_values[t_media]) style_pi->media=(char *)xmlStringDecodeEntities(ctxt, (xmlChar *)xml_stylesheet_values[t_media], XML_SUBSTITUTE_REF|XML_SUBSTITUTE_PEREF, 0, 0, 0); else style_pi->media=NULL; /* Link to nodes chain */ XML_LINK_PI(document, pi, style_pi); } else { mxslt_error(document, "warning - <modxslt-stylesheet type=\"... unknown: '%s'!\n", type); xmlFree(type); } } if(xml_stylesheet_values[t_media]) xfree(xml_stylesheet_values[t_media]); if(xml_stylesheet_values[t_href]) xfree(xml_stylesheet_values[t_href]); if(xml_stylesheet_values[t_type]) xfree(xml_stylesheet_values[t_type]); break; default: mxslt_error(document, "warning - unknown modxslt PI: %s in %s\n", target, document->localfile); break; } break; } /* Taken from `processingInstruction' */ switch(ctxt->inSubset) { case 1: xmlAddChild((xmlNodePtr)ctxt->myDoc->intSubset, pi); return; case 2: xmlAddChild((xmlNodePtr)ctxt->myDoc->extSubset, pi); return; } if(!ctxt->myDoc->children || !ctxt->node) { xmlAddChild((xmlNodePtr)ctxt->myDoc, pi); return; } if(ctxt->node->type == XML_ELEMENT_NODE) xmlAddChild(ctxt->node, pi); else xmlAddSibling(ctxt->node, pi); return; error: mxslt_error(document, "warning - weird data while processing PI: %s in %s\n", target, document->localfile); xmlFreeNode(pi); return; }