void
xen_fini(void)
{
    xmlXPathFreeCompExpr(responsePath);
    xmlXPathFreeCompExpr(faultPath);
    responsePath = NULL;
    faultPath = NULL;
}
Example #2
0
/**
*设置XPATH
*@param xpath XPATH的内容
*@return 设置成功返回true,否则返回false;
*/
bool gpl::xml::setXPath(const char* xpath)
{
	xmlXPathCompExprPtr comp;

	comp = xmlXPathCompile(BAD_CAST xpath);
	if (comp == NULL)
		return false;

	if (m_xml->resource != NULL)
	{
		xmlXPathFreeObject(m_xml->resource);
		m_xml->resource = NULL;
	}

	//XPATH解析树输出
	//xmlXPathDebugDumpCompExpr(stdout, comp, 0);
	m_xml->resource = xmlXPathCompiledEval(comp, m_xml->context);

	//XPATH返回结果输出
	//xmlXPathDebugDumpObject(stdout, m_xml->resource, 0);
	xmlXPathFreeCompExpr(comp);
	if (m_xml->resource == NULL)
		return false;

	//该XPATH下无节点数则返回失败
	if (m_xml->resource->nodesetval == NULL || m_xml->resource->nodesetval->nodeNr == 0)
		return false;

	return true;
}
Example #3
0
xmlXPathObjectPtr
pgxml_xpath(text *document, xmlChar * xpath)
{

	xmlDocPtr	doctree;
	xmlXPathContextPtr ctxt;
	xmlXPathObjectPtr res;

	xmlXPathCompExprPtr comppath;

	int32		docsize;


	docsize = VARSIZE(document) - VARHDRSZ;

	pgxml_parser_init();

	doctree = xmlParseMemory((char *) VARDATA(document), docsize);
	if (doctree == NULL)
	{							/* not well-formed */
		return NULL;
	}

	ctxt = xmlXPathNewContext(doctree);
	ctxt->node = xmlDocGetRootElement(doctree);


	/* compile the path */
	comppath = xmlXPathCompile(xpath);
	if (comppath == NULL)
	{
		xmlCleanupParser();
		xmlFreeDoc(doctree);
		elog_error(ERROR, "XPath Syntax Error", 1);

		return NULL;
	}

	/* Now evaluate the path expression. */
	res = xmlXPathCompiledEval(comppath, ctxt);
	xmlXPathFreeCompExpr(comppath);

	if (res == NULL)
	{
		xmlXPathFreeContext(ctxt);
		/* xmlCleanupParser(); */
		xmlFreeDoc(doctree);

		return NULL;
	}
	/* xmlFreeDoc(doctree); */
	return res;
}
Example #4
0
/**
 * xsltFreeKeyDef:
 * @keyd:  an XSLT key definition
 *
 * Free up the memory allocated by @keyd
 */
static void
xsltFreeKeyDef(xsltKeyDefPtr keyd) {
    if (keyd == NULL)
	return;
    if (keyd->comp != NULL)
	xmlXPathFreeCompExpr(keyd->comp);
    if (keyd->usecomp != NULL)
	xmlXPathFreeCompExpr(keyd->usecomp);
    if (keyd->name != NULL)
	xmlFree(keyd->name);
    if (keyd->nameURI != NULL)
	xmlFree(keyd->nameURI);
    if (keyd->match != NULL)
	xmlFree(keyd->match);
    if (keyd->use != NULL)
	xmlFree(keyd->use);
    if (keyd->nsList != NULL)
        xmlFree(keyd->nsList);
    memset(keyd, -1, sizeof(xsltKeyDef));
    xmlFree(keyd);
}
Example #5
0
static xmlXPathObjectPtr
pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
{
	int32		docsize = VARSIZE(document) - VARHDRSZ;
	PgXmlErrorContext *xmlerrcxt;
	xmlXPathCompExprPtr comppath;

	workspace->doctree = NULL;
	workspace->ctxt = NULL;
	workspace->res = NULL;

	xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);

	PG_TRY();
	{
		workspace->doctree = xmlParseMemory((char *) VARDATA(document),
											docsize);
		if (workspace->doctree != NULL)
		{
			workspace->ctxt = xmlXPathNewContext(workspace->doctree);
			workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);

			/* compile the path */
			comppath = xmlXPathCompile(xpath);
			if (comppath == NULL)
				xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
							"XPath Syntax Error");

			/* Now evaluate the path expression. */
			workspace->res = xmlXPathCompiledEval(comppath, workspace->ctxt);

			xmlXPathFreeCompExpr(comppath);
		}
	}
	PG_CATCH();
	{
		cleanup_workspace(workspace);

		pg_xml_done(xmlerrcxt, true);

		PG_RE_THROW();
	}
	PG_END_TRY();

	if (workspace->res == NULL)
		cleanup_workspace(workspace);

	pg_xml_done(xmlerrcxt, false);

	return workspace->res;
}
Example #6
0
const XMLXPath *XMLDocument::makeXPathQuery(const char *query, char **namespaces, int length, const XMLElement * e, std::string * error)
{
    errorXPathBuffer.clear();

    xmlXPathContext *ctxt = xmlXPathNewContext(document);

    if (!ctxt)
    {
        errorXPathBuffer.append(gettext("Cannot create a parser context"));
        *error = errorXPathBuffer;
        return 0;
    }

    if (e)
    {
        ctxt->node = (xmlNode *) e->getRealXMLPointer();
    }

    if (namespaces)
    {
        for (int i = 0; i < length; i++)
        {
            xmlXPathRegisterNs(ctxt, (const xmlChar *)namespaces[i], (const xmlChar *)namespaces[i + length]);
        }
    }

    xmlSetStructuredErrorFunc(ctxt, XMLDocument::errorXPathFunction);
    xmlXPathCompExpr *expr = xmlXPathCtxtCompile(ctxt, (const xmlChar *)query);

    if (!expr)
    {
        xmlSetStructuredErrorFunc(ctxt, 0);
        xmlXPathFreeContext(ctxt);
        *error = errorXPathBuffer;
        return 0;
    }

    xmlXPathObject *xpath = xmlXPathCompiledEval(expr, ctxt);

    xmlSetStructuredErrorFunc(ctxt, 0);
    xmlXPathFreeContext(ctxt);
    xmlXPathFreeCompExpr(expr);
    if (!xpath)
    {
        *error = errorXPathBuffer;
        return 0;
    }

    return new XMLXPath(*this, xpath);
}
Example #7
0
/**
 * xsltFreeAttrVT:
 * @avt: pointer to an xsltAttrVT structure
 *
 * Free up the memory associated to the attribute value template
 */
static void
xsltFreeAttrVT(xsltAttrVTPtr avt) {
    int i;

    if (avt == NULL) return;

    if (avt->strstart == 1) {
	for (i = 0;i < avt->nb_seg; i += 2)
	    if (avt->segments[i] != NULL)
		xmlFree((xmlChar *) avt->segments[i]);
	for (i = 1;i < avt->nb_seg; i += 2)
	    xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
    } else {
	for (i = 0;i < avt->nb_seg; i += 2)
	    xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
	for (i = 1;i < avt->nb_seg; i += 2)
	    if (avt->segments[i] != NULL)
		xmlFree((xmlChar *) avt->segments[i]);
    }
    if (avt->nsList != NULL)
        xmlFree(avt->nsList);
    xmlFree(avt);
}
Example #8
0
/**
 * xmlSchematronFreeTests:
 * @tests:  a list of tests
 *
 * Free a list of tests.
 */
static void
xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
    xmlSchematronTestPtr next;

    while (tests != NULL) {
        next = tests->next;
	if (tests->test != NULL)
	    xmlFree(tests->test);
	if (tests->comp != NULL)
	    xmlXPathFreeCompExpr(tests->comp);
	if (tests->report != NULL)
	    xmlFree(tests->report);
	xmlFree(tests);
	tests = next;
    }
}
Example #9
0
 void xpath::init_raw_(const std::string& str)
 {
     // Compile the XPath expression.
     xmlXPathCompExpr* px = xmlXPathCompile(detail::to_xml_chars(str.c_str()));
     if (px == 0)
     {
         std::string what = "fail to compile XPath expression: " + str;
         throw xpath_error(what);
     }
     // Free the underlying XPath expression object as necessary.
     if (raw_ != 0)
     {
         xmlXPathFreeCompExpr(raw_);
         raw_ = 0;
     }
     // Reset raw.
     raw_ = px;
 }
Example #10
0
static xmlXPathObjectPtr
pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
{
	int32		docsize = VARSIZE(document) - VARHDRSZ;
	xmlXPathObjectPtr res;
	xmlXPathCompExprPtr comppath;

	workspace->doctree = NULL;
	workspace->ctxt = NULL;
	workspace->res = NULL;

	pgxml_parser_init();

	workspace->doctree = xmlParseMemory((char *) VARDATA(document), docsize);
	if (workspace->doctree == NULL)
		return NULL;			/* not well-formed */

	workspace->ctxt = xmlXPathNewContext(workspace->doctree);
	workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);

	/* compile the path */
	comppath = xmlXPathCompile(xpath);
	if (comppath == NULL)
	{
		cleanup_workspace(workspace);
		xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
					"XPath Syntax Error");
	}

	/* Now evaluate the path expression. */
	res = xmlXPathCompiledEval(comppath, workspace->ctxt);
	workspace->res = res;

	xmlXPathFreeCompExpr(comppath);

	if (res == NULL)
		cleanup_workspace(workspace);

	return res;
}
GAIAGEO_DECLARE int
gaiaIsValidXPathExpression (const void *p_cache, const char *xpath_expr)
{
    struct splite_internal_cache *cache =
	(struct splite_internal_cache *) p_cache;
    xmlXPathCompExprPtr result;
    xmlGenericErrorFunc xpathError;
    if (!is_valid_cache (cache))
	return 0;
    xpathError = (xmlGenericErrorFunc) vxpathError;

    vxpathResetXmlErrors (cache);
    xmlSetGenericErrorFunc (cache, xpathError);

/* testing an XPath expression */
    result = xmlXPathCompile ((const xmlChar *) xpath_expr);
    xmlSetGenericErrorFunc ((void *) stderr, NULL);
    if (result)
      {
	  xmlXPathFreeCompExpr (result);
	  return 1;
      }
    return 0;
}
Example #12
0
static void
testXPath(const char *str) {
    xmlXPathObjectPtr res;
    xmlXPathContextPtr ctxt;

#if defined(LIBXML_XPTR_ENABLED)
    if (xptr) {
	ctxt = xmlXPtrNewContext(document, NULL, NULL);
	res = xmlXPtrEval(BAD_CAST str, ctxt);
    } else {
#endif
	ctxt = xmlXPathNewContext(document);
	ctxt->node = xmlDocGetRootElement(document);
	if (expr)
	    res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
	else {
	    /* res = xmlXPathEval(BAD_CAST str, ctxt); */
	    xmlXPathCompExprPtr comp;

	    comp = xmlXPathCompile(BAD_CAST str);
	    if (comp != NULL) {
		if (tree)
		    xmlXPathDebugDumpCompExpr(stdout, comp, 0);

		res = xmlXPathCompiledEval(comp, ctxt);
		xmlXPathFreeCompExpr(comp);
	    } else
		res = NULL;
	}
#if defined(LIBXML_XPTR_ENABLED)
    }
#endif
    xmlXPathDebugDumpObject(stdout, res, 0);
    xmlXPathFreeObject(res);
    xmlXPathFreeContext(ctxt);
}
Example #13
0
xmlXPathObjectPtr get_nodes_with_name_xpath( XMLDoc *tree, FeriteString *str ) 
{
    char *xpath, *x = "descendant-or-self::node()";	
    xmlXPathCompExprPtr comp = NULL;
    int length = strlen( x ) + str->length + 4;
    
    xpath = malloc(length);
    memset(xpath, '\0', length );
    sprintf( xpath, "%s/%s", x, str->data );
    comp = xmlXPathCompile( BAD_CAST xpath );
    free(xpath);
    
    if( comp != NULL ) {
        xmlXPathObjectPtr res = NULL; 
        xmlXPathContextPtr ctxt = xmlXPathNewContext( tree->doc );
        
        ctxt->node = tree->node;
        res = xmlXPathCompiledEval( comp, ctxt );
        xmlXPathFreeContext( ctxt );
        xmlXPathFreeCompExpr( comp );  
        return res;
    }
    return NULL;
}
Example #14
0
Datum
xpath_table(PG_FUNCTION_ARGS)
{
	/* Function parameters */
	char	   *pkeyfield = text_to_cstring(PG_GETARG_TEXT_PP(0));
	char	   *xmlfield = text_to_cstring(PG_GETARG_TEXT_PP(1));
	char	   *relname = text_to_cstring(PG_GETARG_TEXT_PP(2));
	char	   *xpathset = text_to_cstring(PG_GETARG_TEXT_PP(3));
	char	   *condition = text_to_cstring(PG_GETARG_TEXT_PP(4));

	/* SPI (input tuple) support */
	SPITupleTable *tuptable;
	HeapTuple	spi_tuple;
	TupleDesc	spi_tupdesc;

	/* Output tuple (tuplestore) support */
	Tuplestorestate *tupstore = NULL;
	TupleDesc	ret_tupdesc;
	HeapTuple	ret_tuple;

	ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
	AttInMetadata *attinmeta;
	MemoryContext per_query_ctx;
	MemoryContext oldcontext;

	char	  **values;
	xmlChar   **xpaths;
	char	   *pos;
	const char *pathsep = "|";

	int			numpaths;
	int			ret;
	int			proc;
	int			i;
	int			j;
	int			rownr;			/* For issuing multiple rows from one original
								 * document */
	bool		had_values;		/* To determine end of nodeset results */
	StringInfoData query_buf;
	PgXmlErrorContext *xmlerrcxt;
	volatile xmlDocPtr doctree = NULL;

	/* We only have a valid tuple description in table function mode */
	if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("set-valued function called in context that cannot accept a set")));
	if (rsinfo->expectedDesc == NULL)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("xpath_table must be called as a table function")));

	/*
	 * We want to materialise because it means that we don't have to carry
	 * libxml2 parser state between invocations of this function
	 */
	if (!(rsinfo->allowedModes & SFRM_Materialize))
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
			   errmsg("xpath_table requires Materialize mode, but it is not "
					  "allowed in this context")));

	/*
	 * The tuplestore must exist in a higher context than this function call
	 * (per_query_ctx is used)
	 */
	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
	oldcontext = MemoryContextSwitchTo(per_query_ctx);

	/*
	 * Create the tuplestore - work_mem is the max in-memory size before a
	 * file is created on disk to hold it.
	 */
	tupstore =
		tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
							  false, work_mem);

	MemoryContextSwitchTo(oldcontext);

	/* get the requested return tuple description */
	ret_tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);

	/* must have at least one output column (for the pkey) */
	if (ret_tupdesc->natts < 1)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("xpath_table must have at least one output column")));

	/*
	 * At the moment we assume that the returned attributes make sense for the
	 * XPath specififed (i.e. we trust the caller). It's not fatal if they get
	 * it wrong - the input function for the column type will raise an error
	 * if the path result can't be converted into the correct binary
	 * representation.
	 */

	attinmeta = TupleDescGetAttInMetadata(ret_tupdesc);

	/* Set return mode and allocate value space. */
	rsinfo->returnMode = SFRM_Materialize;
	rsinfo->setDesc = ret_tupdesc;

	values = (char **) palloc(ret_tupdesc->natts * sizeof(char *));
	xpaths = (xmlChar **) palloc(ret_tupdesc->natts * sizeof(xmlChar *));

	/*
	 * Split XPaths. xpathset is a writable CString.
	 *
	 * Note that we stop splitting once we've done all needed for tupdesc
	 */
	numpaths = 0;
	pos = xpathset;
	while (numpaths < (ret_tupdesc->natts - 1))
	{
		xpaths[numpaths++] = (xmlChar *) pos;
		pos = strstr(pos, pathsep);
		if (pos != NULL)
		{
			*pos = '\0';
			pos++;
		}
		else
			break;
	}

	/* Now build query */
	initStringInfo(&query_buf);

	/* Build initial sql statement */
	appendStringInfo(&query_buf, "SELECT %s, %s FROM %s WHERE %s",
					 pkeyfield,
					 xmlfield,
					 relname,
					 condition);

	if ((ret = SPI_connect()) < 0)
		elog(ERROR, "xpath_table: SPI_connect returned %d", ret);

	if ((ret = SPI_exec(query_buf.data, 0)) != SPI_OK_SELECT)
		elog(ERROR, "xpath_table: SPI execution failed for query %s",
			 query_buf.data);

	proc = SPI_processed;
	/* elog(DEBUG1,"xpath_table: SPI returned %d rows",proc); */
	tuptable = SPI_tuptable;
	spi_tupdesc = tuptable->tupdesc;

	/* Switch out of SPI context */
	MemoryContextSwitchTo(oldcontext);

	/*
	 * Check that SPI returned correct result. If you put a comma into one of
	 * the function parameters, this will catch it when the SPI query returns
	 * e.g. 3 columns.
	 */
	if (spi_tupdesc->natts != 2)
	{
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						errmsg("expression returning multiple columns is not valid in parameter list"),
						errdetail("Expected two columns in SPI result, got %d.", spi_tupdesc->natts)));
	}

	/*
	 * Setup the parser.  This should happen after we are done evaluating the
	 * query, in case it calls functions that set up libxml differently.
	 */
	xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);

	PG_TRY();
	{
		/* For each row i.e. document returned from SPI */
		for (i = 0; i < proc; i++)
		{
			char	   *pkey;
			char	   *xmldoc;
			xmlXPathContextPtr ctxt;
			xmlXPathObjectPtr res;
			xmlChar    *resstr;
			xmlXPathCompExprPtr comppath;

			/* Extract the row data as C Strings */
			spi_tuple = tuptable->vals[i];
			pkey = SPI_getvalue(spi_tuple, spi_tupdesc, 1);
			xmldoc = SPI_getvalue(spi_tuple, spi_tupdesc, 2);

			/*
			 * Clear the values array, so that not-well-formed documents
			 * return NULL in all columns.	Note that this also means that
			 * spare columns will be NULL.
			 */
			for (j = 0; j < ret_tupdesc->natts; j++)
				values[j] = NULL;

			/* Insert primary key */
			values[0] = pkey;

			/* Parse the document */
			if (xmldoc)
				doctree = xmlParseMemory(xmldoc, strlen(xmldoc));
			else	/* treat NULL as not well-formed */
				doctree = NULL;

			if (doctree == NULL)
			{
				/* not well-formed, so output all-NULL tuple */
				ret_tuple = BuildTupleFromCStrings(attinmeta, values);
				tuplestore_puttuple(tupstore, ret_tuple);
				heap_freetuple(ret_tuple);
			}
			else
			{
				/* New loop here - we have to deal with nodeset results */
				rownr = 0;

				do
				{
					/* Now evaluate the set of xpaths. */
					had_values = false;
					for (j = 0; j < numpaths; j++)
					{
						ctxt = xmlXPathNewContext(doctree);
						ctxt->node = xmlDocGetRootElement(doctree);

						/* compile the path */
						comppath = xmlXPathCompile(xpaths[j]);
						if (comppath == NULL)
							xml_ereport(xmlerrcxt, ERROR,
										ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
										"XPath Syntax Error");

						/* Now evaluate the path expression. */
						res = xmlXPathCompiledEval(comppath, ctxt);
						xmlXPathFreeCompExpr(comppath);

						if (res != NULL)
						{
							switch (res->type)
							{
								case XPATH_NODESET:
									/* We see if this nodeset has enough nodes */
									if (res->nodesetval != NULL &&
										rownr < res->nodesetval->nodeNr)
									{
										resstr = xmlXPathCastNodeToString(res->nodesetval->nodeTab[rownr]);
										had_values = true;
									}
									else
										resstr = NULL;

									break;

								case XPATH_STRING:
									resstr = xmlStrdup(res->stringval);
									break;

								default:
									elog(NOTICE, "unsupported XQuery result: %d", res->type);
									resstr = xmlStrdup((const xmlChar *) "<unsupported/>");
							}

							/*
							 * Insert this into the appropriate column in the
							 * result tuple.
							 */
							values[j + 1] = (char *) resstr;
						}
						xmlXPathFreeContext(ctxt);
					}

					/* Now add the tuple to the output, if there is one. */
					if (had_values)
					{
						ret_tuple = BuildTupleFromCStrings(attinmeta, values);
						tuplestore_puttuple(tupstore, ret_tuple);
						heap_freetuple(ret_tuple);
					}

					rownr++;
				} while (had_values);
			}

			if (doctree != NULL)
				xmlFreeDoc(doctree);
			doctree = NULL;

			if (pkey)
				pfree(pkey);
			if (xmldoc)
				pfree(xmldoc);
		}
	}
	PG_CATCH();
	{
		if (doctree != NULL)
			xmlFreeDoc(doctree);

		pg_xml_done(xmlerrcxt, true);

		PG_RE_THROW();
	}
	PG_END_TRY();

	if (doctree != NULL)
		xmlFreeDoc(doctree);

	pg_xml_done(xmlerrcxt, false);

	tuplestore_donestoring(tupstore);

	SPI_finish();

	rsinfo->setResult = tupstore;

	/*
	 * SFRM_Materialize mode expects us to return a NULL Datum. The actual
	 * tuples are in our tuplestore and passed back through rsinfo->setResult.
	 * rsinfo->setDesc is set to the tuple description that we actually used
	 * to build our tuples with, so the caller can verify we did what it was
	 * expecting.
	 */
	return (Datum) 0;
}
Example #15
0
 xpath::~xpath()
 {
     assert(raw_ != 0);
     xmlXPathFreeCompExpr(raw_);
     raw_ = 0;
 }
Example #16
0
/**
 *  'update' operation
 */
static void
edUpdate(xmlDocPtr doc, xmlNodeSetPtr nodes, const char *val,
    XmlNodeType type, xmlXPathContextPtr ctxt)
{
    int i;
    xmlXPathCompExprPtr xpath = NULL;

    if (type == XML_EXPR) {
        xpath = xmlXPathCompile((const xmlChar*) val);
        if (!xpath) return;
    }

    for (i = 0; i < nodes->nodeNr; i++)
    {
        /* update node */
        if (type == XML_EXPR) {
            xmlXPathObjectPtr res;

            ctxt->node = nodes->nodeTab[i];
            res = xmlXPathCompiledEval(xpath, ctxt);
            if (res->type == XPATH_NODESET || res->type == XPATH_XSLT_TREE) {
                int j;
                xmlNodePtr oldChild;
                xmlNodeSetPtr oldChildren = xmlXPathNodeSetCreate(NULL);
                /* NOTE: newChildren can be NULL for empty result set */
                xmlNodeSetPtr newChildren = res->nodesetval;

                /* NOTE: nodes can be both oldChildren and newChildren */

                /* unlink the old children */
                for (oldChild = nodes->nodeTab[i]->children; oldChild; oldChild = oldChild->next) {
                    xmlUnlinkNode(oldChild);
                    /* we can't free it now because an oldChild can also be
                       newChild! just put it in the list */
                    xmlXPathNodeSetAdd(oldChildren, oldChild);
                }

                /* add the new children */
                for (j = 0; newChildren && j < newChildren->nodeNr; j++) {
                    xmlNodePtr node = newChildren->nodeTab[j];
                    xmlAddChild(nodes->nodeTab[i],
                        /* if node is linked to this doc we need to copy */
                        (node->doc == doc)? xmlDocCopyNode(node, doc, 1) : node);
                    newChildren->nodeTab[j] = NULL;
                }
                newChildren->nodeNr = 0;

                /* NOTE: if any oldChildren were newChildren, they've been
                   copied so we can free them all now */
                for (j = 0; j < oldChildren->nodeNr; j++) {
                    xmlFreeNode(oldChildren->nodeTab[j]);
                    oldChildren->nodeTab[j] = NULL;
                }
                oldChildren->nodeNr = 0;
                xmlXPathFreeNodeSet(oldChildren);
            } else {
                res = xmlXPathConvertString(res);
                update_string(doc, nodes->nodeTab[i], res->stringval);
            }
            xmlXPathFreeObject(res);
        } else {
            update_string(doc, nodes->nodeTab[i], (const xmlChar*) val);
        }
    }

    xmlXPathFreeCompExpr(xpath);
}
Example #17
0
/**
 * xsltAttrTemplateValueProcessNode:
 * @ctxt:  the XSLT transformation context
 * @str:  the attribute template node value
 * @inst:  the instruction (or LRE) in the stylesheet holding the
 *         attribute with an AVT
 *
 * Process the given string, allowing to pass a namespace mapping
 * context and return the new string value.
 *
 * Called by:
 *  - xsltAttrTemplateValueProcess() (templates.c)
 *  - xsltEvalAttrValueTemplate() (templates.c)
 *
 * QUESTION: Why is this function public? It is not used outside
 *  of templates.c.
 *
 * Returns the computed string value or NULL, must be deallocated by the
 *    caller.
 */
xmlChar *
xsltAttrTemplateValueProcessNode(xsltTransformContextPtr ctxt,
	  const xmlChar *str, xmlNodePtr inst)
{
    xmlChar *ret = NULL;
    const xmlChar *cur;
    xmlChar *expr, *val;
    xmlNsPtr *nsList = NULL;
    int nsNr = 0;

    if (str == NULL) return(NULL);
    if (*str == 0)
	return(xmlStrndup((xmlChar *)"", 0));

    cur = str;
    while (*cur != 0) {
	if (*cur == '{') {
	    if (*(cur+1) == '{') {	/* escaped '{' */
	        cur++;
		ret = xmlStrncat(ret, str, cur - str);
		cur++;
		str = cur;
		continue;
	    }
	    ret = xmlStrncat(ret, str, cur - str);
	    str = cur;
	    cur++;
	    while ((*cur != 0) && (*cur != '}')) cur++;
	    if (*cur == 0) {
	        xsltTransformError(ctxt, NULL, inst,
			"xsltAttrTemplateValueProcessNode: unmatched '{'\n");
		ret = xmlStrncat(ret, str, cur - str);
		return(ret);
	    }
	    str++;
	    expr = xmlStrndup(str, cur - str);
	    if (expr == NULL)
		return(ret);
	    else if (*expr == '{') {
		ret = xmlStrcat(ret, expr);
		xmlFree(expr);
	    } else {
		xmlXPathCompExprPtr comp;
		/*
		 * TODO: keep precompiled form around
		 */
		if ((nsList == NULL) && (inst != NULL)) {
		    int i = 0;

		    nsList = xmlGetNsList(inst->doc, inst);
		    if (nsList != NULL) {
			while (nsList[i] != NULL)
			    i++;
			nsNr = i;
		    }
		}
		comp = xmlXPathCompile(expr);
                val = xsltEvalXPathStringNs(ctxt, comp, nsNr, nsList);
		xmlXPathFreeCompExpr(comp);
		xmlFree(expr);
		if (val != NULL) {
		    ret = xmlStrcat(ret, val);
		    xmlFree(val);
		}
	    }
	    cur++;
	    str = cur;
	} else if (*cur == '}') {
	    cur++;
	    if (*cur == '}') {	/* escaped '}' */
		ret = xmlStrncat(ret, str, cur - str);
		cur++;
		str = cur;
		continue;
	    } else {
	        xsltTransformError(ctxt, NULL, inst,
		     "xsltAttrTemplateValueProcessNode: unmatched '}'\n");
	    }
	} else
	    cur++;
    }
    if (cur != str) {
	ret = xmlStrncat(ret, str, cur - str);
    }

    if (nsList != NULL)
	xmlFree(nsList);

    return(ret);
}
Example #18
0
/**
 *  fastxml_xpath_search provides a common xpath search function for
 * the libraries bits (node, doc). it handles mangling non-namespaced
 * xpath queries into something libxml will play nice with
 */
VALUE fastxml_xpath_search(VALUE self, VALUE raw_xpath, VALUE blk)
{
    VALUE ret, dv, xpath_s;
	xmlXPathCompExprPtr xpath_xpr;
    xmlXPathContextPtr xpath_ctx; 
    xmlXPathObjectPtr xpath_obj;     
    fxml_data_t *data;
    xmlChar *xpath_expr;
	xmlNodePtr root = NULL;
	xmlNsPtr *ns_list = NULL;
	xmlNsPtr *cur_ns = NULL;
	xmlChar *root_ns = NULL;
	int ns_cnt = 0;

    if (NIL_P(raw_xpath)) 
        rb_raise(rb_eArgError, "nil passed as xpath");

    dv = rb_iv_get( self, "@lxml_doc" );    
    Data_Get_Struct( dv, fxml_data_t, data ); 

    xpath_ctx = xmlXPathNewContext( data->doc );
    if (xpath_ctx == NULL) 
        rb_raise( rb_eRuntimeError, "unable to create xpath context" );

	root = data->node;
	if (root == NULL)
		root = xmlDocGetRootElement( data->doc );
		
	xpath_ctx->node = root;
	cur_ns = ns_list = xmlGetNsList( data->doc, root );
	while (cur_ns != NULL && (*cur_ns) != NULL) { 
		xmlXPathRegisterNs( xpath_ctx, (*cur_ns)->prefix, (*cur_ns)->href );
		cur_ns++;
	}

    if (ns_list != NULL) {
	    xpath_ctx->namespaces = ns_list;
	    xpath_ctx->nsNr = ns_cnt;
    }
	
	xpath_s = rb_obj_as_string( raw_xpath );
	if (root->ns != NULL) { // we have a base namespace, this is going to get "interesting"
		root_ns = (xmlChar*)root->ns->prefix;
		if (root_ns == NULL) 
			root_ns = (xmlChar*)"__myFunkyLittleRootNsNotToBeUseByAnyoneElseIHope__"; 
            // alternatives? how do other xpath processors handle root/default namespaces?

		xmlXPathRegisterNs( xpath_ctx, root_ns, root->ns->href );
		// need to update the xpath expression
		xpath_s = munge_xpath_namespace( xpath_s, root_ns );
		xpath_ctx->nsNr++;
	}
	
	xpath_expr = (xmlChar*)RSTRING_PTR(xpath_s);
	xpath_xpr = xmlXPathCompile( xpath_expr );
	if (xpath_xpr == NULL) {
		xmlXPathFreeContext( xpath_ctx );
		xmlFree( ns_list );		
		rb_raise( rb_eRuntimeError, "unable to evaluate xpath expression" );
	}	

	xpath_obj = xmlXPathCompiledEval( xpath_xpr, xpath_ctx );
    if (xpath_obj == NULL) {
        rb_raise( rb_eRuntimeError, "unable to evaluate xpath expression" );
		xmlXPathFreeCompExpr( xpath_xpr );
        xmlXPathFreeContext( xpath_ctx ); 
		xmlFree( ns_list );
        return Qnil;
    }    

    ret = fastxml_nodeset_to_obj( xpath_obj, data );

	xmlFree( ns_list );
	xmlXPathFreeCompExpr( xpath_xpr );
    xmlXPathFreeContext( xpath_ctx ); 

    return ret;	
}
Example #19
0
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;
}
Example #20
0
static void
exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *str = NULL;
    xmlNodeSetPtr nodeset = NULL;
    xsltTransformContextPtr tctxt;
    xmlXPathCompExprPtr comp = NULL;
    xmlXPathObjectPtr ret = NULL;
    xmlDocPtr oldDoc, container = NULL;
    xmlNodePtr oldNode;
    int oldContextSize;
    int oldProximityPosition;
    int i, j;


    if (nargs != 2) {
        xmlXPathSetArityError(ctxt);
        return;
    }
    str = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }

    nodeset = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }
    if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
        if (nodeset != NULL)
            xmlXPathFreeNodeSet(nodeset);
        if (str != NULL)
            xmlFree(str);
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
        return;
    }

    ret = xmlXPathNewNodeSet(NULL);
    if (ret == NULL) {
        xsltGenericError(xsltGenericErrorContext,
                         "exsltDynMapFunction: ret == NULL\n");
        goto cleanup;
    }

    oldDoc = ctxt->context->doc;
    oldNode = ctxt->context->node;
    oldContextSize = ctxt->context->contextSize;
    oldProximityPosition = ctxt->context->proximityPosition;

    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	      "dyn:map : internal error tctxt == NULL\n");
	goto cleanup;
    }
    container = xsltCreateRVT(tctxt);
    if (container == NULL) {
	xsltTransformError(tctxt, NULL, NULL,
	      "dyn:map : internal error container == NULL\n");
	goto cleanup;
    }
    xsltRegisterLocalRVT(tctxt, container);
    if (nodeset && nodeset->nodeNr > 0) {
        xmlXPathNodeSetSort(nodeset);
        ctxt->context->contextSize = nodeset->nodeNr;
        ctxt->context->proximityPosition = 0;
        for (i = 0; i < nodeset->nodeNr; i++) {
            xmlXPathObjectPtr subResult = NULL;

            ctxt->context->proximityPosition++;
            ctxt->context->node = nodeset->nodeTab[i];
            ctxt->context->doc = nodeset->nodeTab[i]->doc;

            subResult = xmlXPathCompiledEval(comp, ctxt->context);
            if (subResult != NULL) {
                switch (subResult->type) {
                    case XPATH_NODESET:
                        if (subResult->nodesetval != NULL)
                            for (j = 0; j < subResult->nodesetval->nodeNr;
                                 j++)
                                xmlXPathNodeSetAdd(ret->nodesetval,
                                                   subResult->nodesetval->
                                                   nodeTab[j]);
                        break;
                    case XPATH_BOOLEAN:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "boolean",
                                            BAD_CAST (subResult->
                                            boolval ? "true" : ""));
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_NUMBER:
                        if (container != NULL) {
                            xmlChar *val =
                                xmlXPathCastNumberToString(subResult->
                                                           floatval);
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "number", val);
                            if (val != NULL)
                                xmlFree(val);

                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_STRING:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "string",
                                            subResult->stringval);
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
		    default:
                        break;
                }
                xmlXPathFreeObject(subResult);
            }
        }
    }
    ctxt->context->doc = oldDoc;
    ctxt->context->node = oldNode;
    ctxt->context->contextSize = oldContextSize;
    ctxt->context->proximityPosition = oldProximityPosition;


  cleanup:
    
    if (comp != NULL)
        xmlXPathFreeCompExpr(comp);
    if (nodeset != NULL)
        xmlXPathFreeNodeSet(nodeset);
    if (str != NULL)
        xmlFree(str);
    valuePush(ctxt, ret);
    return;
}
static void rxml_xpath_expression_free(xmlXPathCompExprPtr expr)
{
  xmlXPathFreeCompExpr(expr);
}
Example #22
0
 //! Free a compiled XPath expression.
 //-----------------------------------------------------------------------
 static void
 free(expression_type const expr)
 {
   xmlXPathFreeCompExpr(expr);
 }