/* * 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); }
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; }