// void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException); static void _setAttributeNS(Request& r, MethodParams& params) { const xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); const xmlChar* qualifiedName=as_xmlqname(r, params, 1); const xmlChar* attribute_value=as_xmlchar(r, params, 2, XML_VALUE_MUST_BE_STRING); VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vxdoc.get_xmldoc(); xmlChar* prefix=0; xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix); // @todo: name=xmlns xmlAttr* attrNode; if(localName) { xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix); attrNode=xmlSetNsProp(&element, &ns, localName, attribute_value); } else { attrNode=xmlSetProp(&element, qualifiedName/*unqualified, actually*/, attribute_value); } if(!attrNode) throw XmlException(0, r); }
/* * call-seq: * attribute(name) * * Get the value of attribute named +name+ */ static VALUE reader_attribute(VALUE self, VALUE name) { xmlTextReaderPtr reader; xmlChar *value ; Data_Get_Struct(self, xmlTextReader, reader); if(name == Qnil) return Qnil; name = StringValue(name) ; value = xmlTextReaderGetAttribute(reader, (xmlChar*)StringValuePtr(name)); if(value == NULL) { /* this section is an attempt to workaround older versions of libxml that don't handle namespaces properly in all attribute-and-friends functions */ xmlChar *prefix = NULL ; xmlChar *localname = xmlSplitQName2((xmlChar*)StringValuePtr(name), &prefix); if (localname != NULL) { value = xmlTextReaderLookupNamespace(reader, localname); xmlFree(localname) ; } else { value = xmlTextReaderLookupNamespace(reader, prefix); } xmlFree(prefix); } if(value == NULL) return Qnil; VALUE MAYBE_UNUSED(enc) = rb_iv_get(self, "@encoding"); VALUE rb_value = NOKOGIRI_STR_NEW2(value, RTEST(enc) ? StringValuePtr(enc) : NULL); xmlFree(value); return rb_value; }
/** * xsltElementAvailableFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the element-available() XSLT function * boolean element-available(string) */ void xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj; xmlChar *prefix, *name; const xmlChar *nsURI = NULL; xsltTransformContextPtr tctxt; if (nargs != 1) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : expects one string arg\n"); ctxt->error = XPATH_INVALID_ARITY; return; } xmlXPathStringFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctxt); tctxt = xsltXPathGetTransformContext(ctxt); if (tctxt == NULL) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : internal error tctxt == NULL\n"); xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewBoolean(0)); return; } name = xmlSplitQName2(obj->stringval, &prefix); if (name == NULL) { xmlNsPtr ns; name = xmlStrdup(obj->stringval); ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL); if (ns != NULL) nsURI = xmlStrdup(ns->href); } else { nsURI = xmlXPathNsLookup(ctxt->context, prefix); if (nsURI == NULL) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : prefix %s is not bound\n", prefix); } } if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) { valuePush(ctxt, xmlXPathNewBoolean(1)); } else { valuePush(ctxt, xmlXPathNewBoolean(0)); } xmlXPathFreeObject(obj); if (name != NULL) xmlFree(name); if (prefix != NULL) xmlFree(prefix); }
/** * xsltFunctionAvailableFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the function-available() XSLT function * boolean function-available(string) */ void xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj; xmlChar *prefix, *name; const xmlChar *nsURI = NULL; if (nargs != 1) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "function-available() : expects one string arg\n"); ctxt->error = XPATH_INVALID_ARITY; return; } if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "function-available() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctxt); name = xmlSplitQName2(obj->stringval, &prefix); if (name == NULL) { name = xmlStrdup(obj->stringval); } else { nsURI = xmlXPathNsLookup(ctxt->context, prefix); if (nsURI == NULL) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "function-available() : prefix %s is not bound\n", prefix); } } if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) { valuePush(ctxt, xmlXPathNewBoolean(1)); } else { valuePush(ctxt, xmlXPathNewBoolean(0)); } xmlXPathFreeObject(obj); if (name != NULL) xmlFree(name); if (prefix != NULL) xmlFree(prefix); }
// Element createElementNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException); static void _createElementNS(Request& r, MethodParams& params) { xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); xmlChar* qualifiedName=as_xmlqname(r, params, 1); VXdoc& vdoc=GET_SELF(r, VXdoc); xmlDoc& xmldoc=vdoc.get_xmldoc(); xmlChar* prefix=0; xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix); xmlNode *node; if(localName) { xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix); node=xmlNewDocNode(&xmldoc, &ns, localName, NULL); } else node=xmlNewDocNode(&xmldoc, NULL, qualifiedName/*unqualified, actually*/, NULL); writeNode(r, vdoc, node); }
/* {{{ proto void DOMElement::__construct(string name, [string value], [string uri]); */ PHP_METHOD(domelement, __construct) { zval *id; xmlNodePtr nodep = NULL, oldnode = NULL; dom_object *intern; char *name, *value = NULL, *uri = NULL; char *localname = NULL, *prefix = NULL; int errorcode = 0, uri_len = 0; int name_len, value_len = 0, name_valid; xmlNsPtr nsptr = NULL; 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!s", &id, dom_element_class_entry, &name, &name_len, &value, &value_len, &uri, &uri_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; } /* Namespace logic is separate and only when uri passed in to insure no BC breakage */ if (uri_len > 0) { errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); if (errorcode == 0) { nodep = xmlNewNode (NULL, (xmlChar *)localname); if (nodep != NULL && uri != NULL) { nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); xmlSetNs(nodep, nsptr); } } xmlFree(localname); if (prefix != NULL) { xmlFree(prefix); } if (errorcode != 0) { if (nodep != NULL) { xmlFreeNode(nodep); } php_dom_throw_error(errorcode, 1 TSRMLS_CC); RETURN_FALSE; } } else { /* If you don't pass a namespace uri, then you can't set a prefix */ localname = xmlSplitQName2((xmlChar *)name, (xmlChar **) &prefix); if (prefix != NULL) { xmlFree(localname); xmlFree(prefix); php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC); RETURN_FALSE; } nodep = xmlNewNode(NULL, (xmlChar *) name); } if (!nodep) { php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); RETURN_FALSE; } if (value_len > 0) { xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len); } 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); } }
/* :nodoc: */ static void relink_namespace(xmlNodePtr reparented) { xmlChar *name, *prefix; xmlNodePtr child; xmlNsPtr ns; if (reparented->type != XML_ATTRIBUTE_NODE && reparented->type != XML_ELEMENT_NODE) return; if (reparented->ns == NULL || reparented->ns->prefix == NULL) { name = xmlSplitQName2(reparented->name, &prefix); if(reparented->type == XML_ATTRIBUTE_NODE) { if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) return; } ns = xmlSearchNs(reparented->doc, reparented, prefix); if (ns == NULL && reparented->parent) { ns = xmlSearchNs(reparented->doc, reparented->parent, prefix); } if (ns != NULL) { xmlNodeSetName(reparented, name); xmlSetNs(reparented, ns); } } /* Avoid segv when relinking against unlinked nodes. */ if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) return; /* Make sure that our reparented node has the correct namespaces */ if(!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent) xmlSetNs(reparented, reparented->parent->ns); /* Search our parents for an existing definition */ if(reparented->nsDef) { xmlNsPtr curr = reparented->nsDef; xmlNsPtr prev = NULL; while(curr) { xmlNsPtr ns = xmlSearchNsByHref( reparented->doc, reparented->parent, curr->href ); /* If we find the namespace is already declared, remove it from this * definition list. */ if(ns && ns != curr) { if (prev) { prev->next = curr->next; } else { reparented->nsDef = curr->next; } nokogiri_root_nsdef(curr, reparented->doc); } else { prev = curr; } curr = curr->next; } } /* Only walk all children if there actually is a namespace we need to */ /* reparent. */ if(NULL == reparented->ns) return; /* When a node gets reparented, walk it's children to make sure that */ /* their namespaces are reparented as well. */ child = reparented->children; while(NULL != child) { relink_namespace(child); child = child->next; } if (reparented->type == XML_ELEMENT_NODE) { child = (xmlNodePtr)((xmlElementPtr)reparented)->attributes; while(NULL != child) { relink_namespace(child); child = child->next; } } }
int xslDbgShellSetVariable(xsltTransformContextPtr styleCtxt, xmlChar * arg) { int result = 0, showUsage = 0; xmlChar *name, *nameURI, *selectExpr, *opts[3]; if (!styleCtxt) { xsldbgGenericErrorFunc(i18n("Error: Stylesheet is not valid.\n")); return result; } if (!arg) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL argument provided\n"); #endif return result; } if (xmlStrLen(arg) > 1) { if (splitString(arg, 2, opts) == 2) { nameURI = NULL; /* ignore any "$" prefix as user probably didn't mean that "$" is part of variable name*/ if (*opts[0] =='$'){ opts[0] = opts[0] + 1; } name = xmlSplitQName2(opts[0], &nameURI); if (name == NULL) name = xmlStrdup(opts[0]); selectExpr = xmlStrdup(opts[1]); if (name && selectExpr) { xsltStackElemPtr def = NULL; if (styleCtxt->varsBase) { /* try finding varaible in stack */ xsltStackElemPtr item = styleCtxt->varsTab[styleCtxt->varsBase]; while (item) { if ((xmlStrCmp(name, item->name) == 0) && (item->nameURI == NULL || (xmlStrCmp(name, item->nameURI) == 0))) { def = item; break; } item = item->next; } } if (def == NULL) def = (xsltStackElemPtr) xmlHashLookup2(styleCtxt->globalVars, name, nameURI); if (def != NULL) { if (def->select) { /* we've found the variable so change it */ xmlFree((void*)def->select); def->select = selectExpr; if (def->comp->comp) xmlXPathFreeCompExpr(def->comp->comp); def->comp->comp = xmlXPathCompile(def->select); if (def->value) xmlXPathFreeObject(def->value); def->value = xmlXPathEval(def->select, styleCtxt->xpathCtxt); result = 1; } else { xmlFree(selectExpr); xsldbgGenericErrorFunc(i18n("Error: Cannot change a variable that does not use the select attribute.\n")); } } else xsldbgGenericErrorFunc(i18n("Error: Variable %1 was not found.\n").arg(xsldbgText(name))); xmlFree(name); } else xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n")); } else { showUsage = 1; } if (showUsage == 1) xsldbgGenericErrorFunc(i18n("Error: Invalid arguments to command %1.\n").arg("set")); } return result; }
/** * xsltSystemPropertyFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the system-property() XSLT function * object system-property(string) */ void xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj; xmlChar *prefix, *name; const xmlChar *nsURI = NULL; if (nargs != 1) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "system-property() : expects one string arg\n"); ctxt->error = XPATH_INVALID_ARITY; return; } if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "system-property() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctxt); if (obj->stringval == NULL) { valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); } else { name = xmlSplitQName2(obj->stringval, &prefix); if (name == NULL) { name = xmlStrdup(obj->stringval); } else { nsURI = xmlXPathNsLookup(ctxt->context, prefix); if (nsURI == NULL) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "system-property() : prefix %s is not bound\n", prefix); } } if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) { #ifdef DOCBOOK_XSL_HACK if (xmlStrEqual(name, (const xmlChar *)"vendor")) { xsltStylesheetPtr sheet; xsltTransformContextPtr tctxt; tctxt = xsltXPathGetTransformContext(ctxt); if ((tctxt != NULL) && (tctxt->inst != NULL) && (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) && (tctxt->inst->parent != NULL) && (xmlStrEqual(tctxt->inst->parent->name, BAD_CAST "template"))) sheet = tctxt->style; else sheet = NULL; if ((sheet != NULL) && (sheet->doc != NULL) && (sheet->doc->URL != NULL) && (xmlStrstr(sheet->doc->URL, (const xmlChar *)"chunk") != NULL)) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)"libxslt (SAXON 6.2 compatible)")); } else { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_VENDOR)); } } else #else if (xmlStrEqual(name, (const xmlChar *)"vendor")) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_VENDOR)); } else #endif if (xmlStrEqual(name, (const xmlChar *)"version")) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_VERSION)); } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_URL)); } else { valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); } } else { valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); } if (name != NULL) xmlFree(name); if (prefix != NULL) xmlFree(prefix); } xmlXPathFreeObject(obj); }
/** * xsltKeyFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the key() XSLT function * node-set key(string, object) */ void xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj1, obj2; if (nargs != 2) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "key() : expects two arguments\n"); ctxt->error = XPATH_INVALID_ARITY; return; } /* * Get the key's value. */ obj2 = valuePop(ctxt); xmlXPathStringFunction(ctxt, 1); if ((obj2 == NULL) || (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj2); return; } /* * Get the key's name. */ obj1 = valuePop(ctxt); if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) { int i; xmlXPathObjectPtr newobj, ret; ret = xmlXPathNewNodeSet(NULL); if (obj2->nodesetval != NULL) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) { valuePush(ctxt, xmlXPathObjectCopy(obj1)); valuePush(ctxt, xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); xmlXPathStringFunction(ctxt, 1); xsltKeyFunction(ctxt, 2); newobj = valuePop(ctxt); ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, newobj->nodesetval); xmlXPathFreeObject(newobj); } } valuePush(ctxt, ret); } else { xmlNodeSetPtr nodelist = NULL; xmlChar *key = NULL, *value; const xmlChar *keyURI; xsltTransformContextPtr tctxt; xmlChar *qname, *prefix; xmlXPathContextPtr xpctxt = ctxt->context; xmlNodePtr tmpNode = NULL; xsltDocumentPtr oldDocInfo; tctxt = xsltXPathGetTransformContext(ctxt); oldDocInfo = tctxt->document; if (xpctxt->node == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "Internal error in xsltKeyFunction(): " "The context node is not set on the XPath context.\n"); tctxt->state = XSLT_STATE_STOPPED; goto error; } /* * Get the associated namespace URI if qualified name */ qname = obj1->stringval; key = xmlSplitQName2(qname, &prefix); if (key == NULL) { key = xmlStrdup(obj1->stringval); keyURI = NULL; if (prefix != NULL) xmlFree(prefix); } else { if (prefix != NULL) { keyURI = xmlXPathNsLookup(xpctxt, prefix); if (keyURI == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "key() : prefix %s is not bound\n", prefix); /* * TODO: Shouldn't we stop here? */ } xmlFree(prefix); } else { keyURI = NULL; } } /* * Force conversion of first arg to string */ valuePush(ctxt, obj2); xmlXPathStringFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(tctxt, NULL, tctxt->inst, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; goto error; } obj2 = valuePop(ctxt); value = obj2->stringval; /* * We need to ensure that ctxt->document is available for * xsltGetKey(). * First find the relevant doc, which is the context node's * owner doc; using context->doc is not safe, since * the doc could have been acquired via the document() function, * or the doc might be a Result Tree Fragment. * FUTURE INFO: In XSLT 2.0 the key() function takes an additional * argument indicating the doc to use. */ if (xpctxt->node->type == XML_NAMESPACE_DECL) { /* * REVISIT: This is a libxml hack! Check xpath.c for details. * The XPath module sets the owner element of a ns-node on * the ns->next field. */ if ((((xmlNsPtr) xpctxt->node)->next != NULL) && (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE)) { tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next; } } else tmpNode = xpctxt->node; if ((tmpNode == NULL) || (tmpNode->doc == NULL)) { xsltTransformError(tctxt, NULL, tctxt->inst, "Internal error in xsltKeyFunction(): " "Couldn't get the doc of the XPath context node.\n"); goto error; } if ((tctxt->document == NULL) || (tctxt->document->doc != tmpNode->doc)) { if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) { /* * This is a Result Tree Fragment. */ if (tmpNode->doc->_private == NULL) { tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc); if (tmpNode->doc->_private == NULL) goto error; } tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private; } else { /* * May be the initial source doc or a doc acquired via the * document() function. */ tctxt->document = xsltFindDocument(tctxt, tmpNode->doc); } if (tctxt->document == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "Internal error in xsltKeyFunction(): " "Could not get the document info of a context doc.\n"); tctxt->state = XSLT_STATE_STOPPED; goto error; } } /* * Get/compute the key value. */ nodelist = xsltGetKey(tctxt, key, keyURI, value); error: tctxt->document = oldDocInfo; valuePush(ctxt, xmlXPathWrapNodeSet( xmlXPathNodeSetMerge(NULL, nodelist))); if (key != NULL) xmlFree(key); } if (obj1 != NULL) xmlXPathFreeObject(obj1); if (obj2 != NULL) xmlXPathFreeObject(obj2); }
/* {{{ proto void DOMElement::__construct(string name, [string value], [string uri]) */ PHP_METHOD(domelement, __construct) { zval *id = getThis(); xmlNodePtr nodep = NULL, oldnode = NULL; dom_object *intern; char *name, *value = NULL, *uri = NULL; char *localname = NULL, *prefix = NULL; int errorcode = 0; size_t name_len, value_len = 0, uri_len = 0; int name_valid; xmlNsPtr nsptr = NULL; if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s|s!s", &name, &name_len, &value, &value_len, &uri, &uri_len) == FAILURE) { return; } name_valid = xmlValidateName((xmlChar *) name, 0); if (name_valid != 0) { php_dom_throw_error(INVALID_CHARACTER_ERR, 1); RETURN_FALSE; } /* Namespace logic is separate and only when uri passed in to insure no BC breakage */ if (uri_len > 0) { errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); if (errorcode == 0) { nodep = xmlNewNode (NULL, (xmlChar *)localname); if (nodep != NULL && uri != NULL) { nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); xmlSetNs(nodep, nsptr); } } xmlFree(localname); if (prefix != NULL) { xmlFree(prefix); } if (errorcode != 0) { if (nodep != NULL) { xmlFreeNode(nodep); } php_dom_throw_error(errorcode, 1); RETURN_FALSE; } } else { /* If you don't pass a namespace uri, then you can't set a prefix */ localname = (char *) xmlSplitQName2((xmlChar *) name, (xmlChar **) &prefix); if (prefix != NULL) { xmlFree(localname); xmlFree(prefix); php_dom_throw_error(NAMESPACE_ERR, 1); RETURN_FALSE; } nodep = xmlNewNode(NULL, (xmlChar *) name); } if (!nodep) { php_dom_throw_error(INVALID_STATE_ERR, 1); RETURN_FALSE; } if (value_len > 0) { xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len); } intern = Z_DOMOBJ_P(id); oldnode = dom_object_get_node(intern); if (oldnode != NULL) { php_libxml_node_free_resource(oldnode ); } php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern); }
/* :nodoc: */ static void relink_namespace(xmlNodePtr reparented) { xmlNodePtr child; if (reparented->type != XML_ATTRIBUTE_NODE && reparented->type != XML_ELEMENT_NODE) { return; } if (reparented->ns == NULL || reparented->ns->prefix == NULL) { xmlNsPtr ns = NULL; xmlChar *name = NULL, *prefix = NULL; name = xmlSplitQName2(reparented->name, &prefix); if (reparented->type == XML_ATTRIBUTE_NODE) { if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) { xmlFree(name); xmlFree(prefix); return; } } ns = xmlSearchNs(reparented->doc, reparented, prefix); if (ns == NULL && reparented->parent) { ns = xmlSearchNs(reparented->doc, reparented->parent, prefix); } if (ns != NULL) { xmlNodeSetName(reparented, name); xmlSetNs(reparented, ns); } xmlFree(name); xmlFree(prefix); } /* Avoid segv when relinking against unlinked nodes. */ if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; } /* Make sure that our reparented node has the correct namespaces */ if (!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent) { xmlSetNs(reparented, reparented->parent->ns); } /* Search our parents for an existing definition */ if (reparented->nsDef) { xmlNsPtr curr = reparented->nsDef; xmlNsPtr prev = NULL; while (curr) { xmlNsPtr ns = xmlSearchNsByHref( reparented->doc, reparented->parent, curr->href ); /* If we find the namespace is already declared, remove it from this * definition list. */ if (ns && ns != curr && xmlStrEqual(ns->prefix, curr->prefix)) { if (prev) { prev->next = curr->next; } else { reparented->nsDef = curr->next; } nokogiri_root_nsdef(curr, reparented->doc); } else { prev = curr; } curr = curr->next; } } /* * Search our parents for an existing definition of current namespace, * because the definition it's pointing to may have just been removed nsDef. * * And although that would technically probably be OK, I'd feel better if we * referred to a namespace that's still present in a node's nsDef somewhere * in the doc. */ if (reparented->ns) { xmlNsPtr ns = xmlSearchNs(reparented->doc, reparented, reparented->ns->prefix); if (ns && ns != reparented->ns && xmlStrEqual(ns->prefix, reparented->ns->prefix) && xmlStrEqual(ns->href, reparented->ns->href) ) { xmlSetNs(reparented, ns); } } /* Only walk all children if there actually is a namespace we need to */ /* reparent. */ if (NULL == reparented->ns) { return; } /* When a node gets reparented, walk it's children to make sure that */ /* their namespaces are reparented as well. */ child = reparented->children; while (NULL != child) { relink_namespace(child); child = child->next; } if (reparented->type == XML_ELEMENT_NODE) { child = (xmlNodePtr)((xmlElementPtr)reparented)->attributes; while(NULL != child) { relink_namespace(child); child = child->next; } } }
/** * xsltKeyFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the key() XSLT function * node-set key(string, object) */ void xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlNodeSetPtr nodelist; xmlXPathObjectPtr obj1, obj2; xmlChar *key = NULL, *value; const xmlChar *keyURI; xsltTransformContextPtr tctxt; if (nargs != 2) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : expects two arguments\n"); ctxt->error = XPATH_INVALID_ARITY; return; } obj2 = valuePop(ctxt); if ((obj2 == NULL) || (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj2); return; } obj1 = valuePop(ctxt); if (obj2->type == XPATH_NODESET) { int i; xmlXPathObjectPtr newobj, ret; ret = xmlXPathNewNodeSet(NULL); if (obj2->nodesetval != NULL) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) { valuePush(ctxt, xmlXPathObjectCopy(obj1)); valuePush(ctxt, xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); xmlXPathStringFunction(ctxt, 1); xsltKeyFunction(ctxt, 2); newobj = valuePop(ctxt); ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, newobj->nodesetval); xmlXPathFreeObject(newobj); } } valuePush(ctxt, ret); } else { xmlChar *qname, *prefix; /* * Get the associated namespace URI if qualified name */ qname = obj1->stringval; key = xmlSplitQName2(qname, &prefix); if (key == NULL) { key = xmlStrdup(obj1->stringval); keyURI = NULL; if (prefix != NULL) xmlFree(prefix); } else { if (prefix != NULL) { keyURI = xmlXPathNsLookup(ctxt->context, prefix); if (keyURI == NULL) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : prefix %s is not bound\n", prefix); } xmlFree(prefix); } else { keyURI = NULL; } } /* * Force conversion of first arg to string */ valuePush(ctxt, obj2); xmlXPathStringFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj1); return; } obj2 = valuePop(ctxt); value = obj2->stringval; tctxt = xsltXPathGetTransformContext(ctxt); nodelist = xsltGetKey(tctxt, key, keyURI, value); valuePush(ctxt, xmlXPathWrapNodeSet( xmlXPathNodeSetMerge(NULL, nodelist))); } if (obj1 != NULL) xmlXPathFreeObject(obj1); if (obj2 != NULL) xmlXPathFreeObject(obj2); if (key != NULL) xmlFree(key); }