Exemple #1
0
/*
 * call-seq:
 *    XML::Node.new_pi(name, content = nil) -> XML::Node
 *
 * Create a new pi node, optionally setting
 * the node's content.
 *
 */
static VALUE rxml_node_new_pi(int argc, VALUE *argv, VALUE klass)
{
  VALUE name = Qnil;
  VALUE content = Qnil;
  xmlNodePtr xnode;

  rb_scan_args(argc, argv, "11", &name, &content);

  if (NIL_P(name))
  {
    rb_raise(rb_eRuntimeError, "You must provide me with a name for a PI.");
  }
  name = rb_obj_as_string(name);
  if (NIL_P(content))
  {
    xnode = xmlNewPI((xmlChar*) StringValuePtr(name), NULL);
  }
  else
  {
    content = rb_obj_as_string(content);
    xnode = xmlNewPI((xmlChar*) StringValuePtr(name), (xmlChar*) StringValueCStr(content));
  }

  if (xnode == NULL)
    rxml_raise(&xmlLastError);

  return rxml_node_wrap(xnode);
}
Exemple #2
0
Node::Node(const string & name, NodeType type, const string & content, const class Namespace & ns)
{
    _xmlNode * newNode = nullptr;
    
    switch (type)
    {
        case NodeType::Element:
            // needs subclass
            break;
            
        case NodeType::Text:
            // needs subclass
            break;
            
        case NodeType::Attribute:
            // Not Applicable
            break;
            
        case NodeType::CDATASection:
#ifdef LIBXML_DOCBOOK_ENABLED
        case NodeType::DocbookSGMLDocument:
#endif
        case NodeType::Document:
        case NodeType::DocumentFragment:
        case NodeType::DTD:
        case NodeType::HTMLDocument:
            // need document ptr to create these
            break;
            
        case NodeType::Comment:
            // needs subclass
            break;
            
        case NodeType::ProcessingInstruction:
            newNode = xmlNewPI(name.utf8(), content.utf8());
            break;
            
        default:
            newNode = xmlNewNode(const_cast<_xmlNs*>(ns.xml()), name.utf8());
            break;
    }
    
    if ( newNode == nullptr )
        throw InvalidNodeType(std::string("NodeType '") + TypeString(type) + "' is not supported");
    
    _xml = newNode;
    _xml->_private = new LibXML2Private<Node>(this);
}
/* {{{ proto void DOMProcessingInstruction::__construct(string name, [string value]); */
PHP_METHOD(domprocessinginstruction, __construct)
{

	zval *id;
	xmlNodePtr nodep = NULL, oldnode = NULL;
	dom_object *intern;
	char *name, *value = NULL;
	int name_len, value_len, name_valid;
	zend_error_handling error_handling;

	zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_processinginstruction_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}

	zend_restore_error_handling(&error_handling TSRMLS_CC);

	name_valid = xmlValidateName((xmlChar *) name, 0);
	if (name_valid != 0) {
		php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
		RETURN_FALSE;
	}

	nodep = xmlNewPI((xmlChar *) name, (xmlChar *) value);

	if (!nodep) {
		php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
		RETURN_FALSE;
	}

	intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
	if (intern != NULL) {
		oldnode = dom_object_get_node(intern);
		if (oldnode != NULL) {
			php_libxml_node_free_resource(oldnode  TSRMLS_CC);
		}
		php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
	}
}
  /* 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;
}