예제 #1
0
	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;
	}
예제 #2
0
  /* 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;
}
예제 #3
0
 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));
 }
예제 #4
0
  /* 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;
}
예제 #5
0
  /* 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;
}