示例#1
0
static xmlXPathObjectPtr evaluate_xpath(xmlDoc *doc, gchar *xpath) {
	
	g_return_val_if_fail(doc != NULL, NULL);
	g_return_val_if_fail(xpath != NULL, NULL);
	
	xmlXPathContextPtr xpathCtx; 
	xmlXPathObjectPtr xpathObj;
	int i = 0;

	/* Create xpath evaluation context */
	xpathCtx = xmlXPathNewContext(doc);

	g_return_val_if_fail(xpathCtx != NULL, NULL);
	
	xmlNsPtr *nsp;
	nsp = xmlGetNsList(doc,xmlDocGetRootElement(doc));

	if (nsp != NULL) {
	  while (nsp[i] != NULL)
	    i++;
	}

	xpathCtx->namespaces = nsp;
	xpathCtx->nsNr = i;
	
	/* Evaluate xpath expression */
	xpathObj = xmlXPathEvalExpression((xmlChar *)xpath, xpathCtx);

	xmlFree(nsp);
	xmlXPathFreeContext(xpathCtx);

	return xpathObj;
}
示例#2
0
/*
 * Same prefix but not same URI 
 */
static bool ows_libxml_check_namespace_node(ows *o, xmlNodePtr n, xmlNsPtr *ns_doc) 
{
    xmlNsPtr *ns_node, *pn, *pd;
    bool ret= true;

    assert(o);
    assert(n);
    assert(ns_doc);

    ns_node = xmlGetNsList(n->doc, n);
    if (!ns_node) return ret;

    for (pn = ns_node ; *(pn) ; pn++) {
       for (pd = ns_doc ; *(pd) ; pd++) {

            if (    (*pn)->prefix && (*pd)->prefix && (*pn)->href && (*pd)->href
                 && !strcmp((char *) (*pn)->prefix, (char *) (*pd)->prefix)
                 &&  strcmp((char *) (*pn)->href,   (char *) (*pd)->href  )) {
                 ret = false;
                 break;
            }
        }
    }

    xmlFree(ns_node);
    return ret;
}
示例#3
0
/**
 * Return false if current element namespace is not a KML one
 * Return true otherwise.
 */
static bool is_kml_namespace(xmlNodePtr xnode, bool is_strict)
{
	xmlNsPtr *ns, *p;

	ns = xmlGetNsList(xnode->doc, xnode);
	/*
	 * If no namespace is available we could return true anyway
	 * (because we work only on KML fragment, we don't want to
	 *  'oblige' to add namespace on the geometry root node)
	 */
	if (ns == NULL) return !is_strict;

	for (p=ns ; *p ; p++)
	{
		if ((*p)->href == NULL) continue;
		if (!strcmp((char *) (*p)->href, KML_NS))
		{
			if (	(*p)->prefix == NULL ||
			        !xmlStrcmp(xnode->ns->prefix, (*p)->prefix))
			{

				xmlFree(ns);
				return true;
			}
		}
	}

	xmlFree(ns);
	return false;
}
示例#4
0
/**@ingroup tsk_xml_group
* Get an XML namespace from an XML document
* @param docPtr A pointer to the XML document
* @param node The XML node from which to extract the namespace
* @param href The namespace href
* @retval The Namespace value matching our criteria (href)
*/
xmlNsPtr tsk_xml_get_namespace(xmlDocPtr docPtr, xmlNodePtr node, const char *href)
{
	xmlNs *ns = *xmlGetNsList(docPtr, node);
	while (ns)
	{
		if (tsk_striequals(ns->href, href)) return ns;
		else ns = ns->next;
	}

	return 0;
}
/* call-seq:
 *    context.register_namespaces_from_node(node) -> self
 *
 * Helper method to read in namespaces defined on a node.
 *
 *  doc = XML::Document.string('<header><first>hi</first></header>')
 *  context = XPath::Context.new(doc)
 *  context.register_namespaces_from_node(doc.root)
 */
static VALUE rxml_xpath_context_register_namespaces_from_node(VALUE self,
    VALUE node)
{
  xmlXPathContextPtr xctxt;
  xmlNodePtr xnode;
  xmlNsPtr *xnsArr;

  Data_Get_Struct(self, xmlXPathContext, xctxt);

  if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
  {
    xmlDocPtr xdoc;
    Data_Get_Struct(node, xmlDoc, xdoc);
    xnode = xmlDocGetRootElement(xdoc);
  }
  else if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
  {
    Data_Get_Struct(node, xmlNode, xnode);
  }
  else
  {
    rb_raise(rb_eTypeError, "The first argument must be a document or node.");
  }

  xnsArr = xmlGetNsList(xnode->doc, xnode);

  if (xnsArr)
  {
    xmlNsPtr xns = *xnsArr;

    while (xns)
    {
      /* If there is no prefix, then this is the default namespace.
       Skip it for now. */
      if (xns->prefix)
      {
        VALUE prefix = rxml_str_new2((const char*)xns->prefix, xctxt->doc->encoding);
        VALUE uri = rxml_str_new2((const char*)xns->href, xctxt->doc->encoding);
        rxml_xpath_context_register_namespace(self, prefix, uri);
      }
      xns = xns->next;
    }
    xmlFree(xnsArr);
  }

  return self;
}
示例#6
0
NamespaceList Node::NamespacesInScope() const
{
    NamespaceList result;
    xmlNsPtr *pNamespaces = xmlGetNsList(_xml->doc, _xml);
    if ( pNamespaces == nullptr )
        return result;
    
    for ( int i = 0; pNamespaces[i] != nullptr; i++ )
    {
        xmlNsPtr xmlNs = pNamespaces[i];
        result.push_back(Wrapped<class Namespace, _xmlNs>(xmlNs));
    }
    
    xmlMemFree(pNamespaces);
    
    return result;
}
示例#7
0
static void
register_namespaces(xmlXPathContextPtr ctxt, WsXmlDocH doc,
		WsXmlNodeH node)
{
	xmlNsPtr *nsList, *cur;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;


	nsList = xmlGetNsList(d, (xmlNodePtr) node);
	if (nsList == NULL) {
		return;
	}
	for (cur = nsList; *cur != NULL; cur++) {
		if (xmlXPathRegisterNs(ctxt, (*cur)->prefix, (*cur)->href)
				!= 0) {
			return;
		}
	}
	xmlFree(nsList);
}
示例#8
0
/*
 *  TODO
 */
bool ows_libxml_check_namespace(ows *o, xmlNodePtr n)
{
    xmlNsPtr *ns_doc;
    xmlNodePtr node;
    bool ret = true;

    assert(o);
    assert(n);

    ns_doc  = xmlGetNsList(n->doc, xmlDocGetRootElement(n->doc));
    if (!ns_doc) return false;

    for (node = n ; node ; node = node->next) {
        if (node->type != XML_ELEMENT_NODE) continue;
        if (node->children && !(ret = ows_libxml_check_namespace(o, node->children))) break;
        if (!(ret = ows_libxml_check_namespace_node(o, node, ns_doc))) break;
    }
   
    xmlFree(ns_doc);
    return ret;
}
示例#9
0
/*
 * Add the whole xml element into the buffer
 */
buffer *cgi_add_xml_into_buffer(buffer * element, xmlNodePtr n)
{
  xmlBufferPtr buf;
  xmlNsPtr * ns;
  int i;

  assert(element);
  assert(n);

  ns = xmlGetNsList(n->doc, n);

  for (i = 0 ; ns[i] ; i++)
    xmlNewNs(n, ns[i]->href, ns[i]->prefix);

  buf = xmlBufferCreate();
  xmlNodeDump(buf, n->doc, n, 0, 0);
  buffer_add_str(element, (char *) buf->content);

  xmlBufferFree(buf);
  xmlFree(ns);

  return element;
}
示例#10
0
文件: xml.cpp 项目: zhenyouluo/GPL
bool gpl::xml::insertNodeByXPath(const char* nodeName, const char* nodeValue, int length /*= -1*/)
{
	if (m_xml->resource == NULL)
		return false;
	int len = strlen(nodeValue);
	if (length == 0 || len < length)
		return false;
	if (length == -1)
	{
		length = len;
	}
	//cout<<"resource->type:"<<m_xml->resource->type<<endl;
	switch (m_xml->resource->type)
	{
	case XPATH_NODESET://Object is a Node Set
		if (m_xml->resource->nodesetval == NULL)
			return false;
		xmlNodePtr cur, newNode;
		//取得第一个节点
		if ((cur = (*(m_xml->resource->nodesetval->nodeTab))) == NULL)
			return false;
		if (strlen(nodeName) == 0)
		{
			if (cur->children == NULL)
			{
				cur->children = xmlNewText((const xmlChar*)nodeValue);
				cur->last = cur->children;
				if (cur->last == NULL)
					return false;
			}
			else
				if (xmlTextConcat(cur->children, (const xmlChar *)nodeValue, length) < 0)
					return false;
		}
		else
		{
			if (strcmp(nodeName, XML_CDATA) == 0)
			{
				if ((newNode = xmlNewCDataBlock(m_xml->doc, (const xmlChar*)nodeValue, length)) == NULL)
					return false;
			}
			else
			{
				xmlNsPtr* ns = xmlGetNsList(m_xml->doc, cur);
				if ((newNode = xmlNewNode((ns == NULL ? NULL : (*ns)), (const xmlChar *)nodeName)) == NULL)
					return false;
				xmlNodeSetContent(newNode, (const xmlChar*)nodeValue);

			}
			//从最后的字节点位置进行追加
			if ((xmlAddChild(cur, newNode)) == NULL)
				return false;
		}
		break;
	case XPATH_XSLT_TREE://Object is an XSLT value tree
	case XPATH_BOOLEAN://Object is a Boolean
	case XPATH_NUMBER://Object is a number
	case XPATH_STRING://Object is a string
	case XPATH_POINT://Object is a point
	case XPATH_RANGE://是一个范围
	case XPATH_LOCATIONSET://Object is a Location Set
	case XPATH_USERS://Object is user defined
	case XPATH_UNDEFINED://Object is uninitialized
		return false;
		break;
	}
	return true;
}
示例#11
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);
}
示例#12
0
文件: xpath.c 项目: 0xhacking/php-src
static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
{
	zval *id, retval, *context = NULL;
	xmlXPathContextPtr ctxp;
	xmlNodePtr nodep = NULL;
	xmlXPathObjectPtr xpathobjp;
	size_t expr_len, nsnbr = 0, xpath_type;
	dom_xpath_object *intern;
	dom_object *nodeobj;
	char *expr;
	xmlDoc *docp = NULL;
	xmlNsPtr *ns = NULL;
	zend_bool register_node_ns = 1;

	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|O!b", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry, &register_node_ns) == FAILURE) {
		return;
	}

	intern = Z_XPATHOBJ_P(id);

	ctxp = (xmlXPathContextPtr) intern->dom.ptr;
	if (ctxp == NULL) {
		php_error_docref(NULL, E_WARNING, "Invalid XPath Context");
		RETURN_FALSE;
	}

	docp = (xmlDocPtr) ctxp->doc;
	if (docp == NULL) {
		php_error_docref(NULL, E_WARNING, "Invalid XPath Document Pointer");
		RETURN_FALSE;
	}

	if (context != NULL) {
		DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj);
	}

	if (!nodep) {
		nodep = xmlDocGetRootElement(docp);
	}

	if (nodep && docp != nodep->doc) {
		php_error_docref(NULL, E_WARNING, "Node From Wrong Document");
		RETURN_FALSE;
	}

	ctxp->node = nodep;

	if (register_node_ns) {
		/* Register namespaces in the node */
		ns = xmlGetNsList(docp, nodep);

		if (ns != NULL) {
			while (ns[nsnbr] != NULL)
			nsnbr++;
		}
	}


    ctxp->namespaces = ns;
    ctxp->nsNr = nsnbr;

	xpathobjp = xmlXPathEvalExpression((xmlChar *) expr, ctxp);
	ctxp->node = NULL;

	if (ns != NULL) {
		xmlFree(ns);
		ctxp->namespaces = NULL;
		ctxp->nsNr = 0;
	}

	if (! xpathobjp) {
		RETURN_FALSE;
	}

	if (type == PHP_DOM_XPATH_QUERY) {
		xpath_type = XPATH_NODESET;
	} else {
		xpath_type = xpathobjp->type;
	}

	switch (xpath_type) {

		case  XPATH_NODESET:
		{
			int i;
			xmlNodeSetPtr nodesetp;

			array_init(&retval);

			if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) {

				for (i = 0; i < nodesetp->nodeNr; i++) {
					xmlNodePtr node = nodesetp->nodeTab[i];
					zval child;

					if (node->type == XML_NAMESPACE_DECL) {
						xmlNsPtr curns;
						xmlNodePtr nsparent;

						nsparent = node->_private;
						curns = xmlNewNs(NULL, node->name, NULL);
						if (node->children) {
							curns->prefix = xmlStrdup((xmlChar *) node->children);
						}
						if (node->children) {
							node = xmlNewDocNode(docp, NULL, (xmlChar *) node->children, node->name);
						} else {
							node = xmlNewDocNode(docp, NULL, (xmlChar *) "xmlns", node->name);
						}
						node->type = XML_NAMESPACE_DECL;
						node->parent = nsparent;
						node->ns = curns;
					}
					php_dom_create_object(node, &child, &intern->dom);
					add_next_index_zval(&retval, &child);
				}
			}
			php_dom_create_interator(return_value, DOM_NODELIST);
			nodeobj = Z_DOMOBJ_P(return_value);
			dom_xpath_iter(&retval, nodeobj);
			break;
		}

		case XPATH_BOOLEAN:
			RETVAL_BOOL(xpathobjp->boolval);
			break;

		case XPATH_NUMBER:
			RETVAL_DOUBLE(xpathobjp->floatval)
			break;

		case XPATH_STRING:
			RETVAL_STRING((char *) xpathobjp->stringval);
			break;

		default:
			RETVAL_NULL();
			break;
	}

	xmlXPathFreeObject(xpathobjp);
}
示例#13
0
/**
 * xsltAddKey:
 * @style: an XSLT stylesheet
 * @name:  the key name or NULL
 * @nameURI:  the name URI or NULL
 * @match:  the match value
 * @use:  the use value
 * @inst: the key instruction
 *
 * add a key definition to a stylesheet
 *
 * Returns 0 in case of success, and -1 in case of failure.
 */
int
xsltAddKey(xsltStylesheetPtr style, const xmlChar *name,
	   const xmlChar *nameURI, const xmlChar *match,
	   const xmlChar *use, xmlNodePtr inst) {
    xsltKeyDefPtr key;
    xmlChar *pattern = NULL;
    int current, end, start, i = 0;

    if ((style == NULL) || (name == NULL) || (match == NULL) || (use == NULL))
	return(-1);

#ifdef WITH_XSLT_DEBUG_KEYS
    xsltGenericDebug(xsltGenericDebugContext,
	"Add key %s, match %s, use %s\n", name, match, use);
#endif

    key = xsltNewKeyDef(name, nameURI);
    key->match = xmlStrdup(match);
    key->use = xmlStrdup(use);
    key->inst = inst;
    key->nsList = xmlGetNsList(inst->doc, inst);
    if (key->nsList != NULL) {
        while (key->nsList[i] != NULL)
	    i++;
    }
    key->nsNr = i;

    /*
     * Split the | and register it as as many keys
     */
    current = end = 0;
    while (match[current] != 0) {
	start = current;
	while (IS_BLANK_CH(match[current]))
	    current++;
	end = current;
	while ((match[end] != 0) && (match[end] != '|')) {
	    if (match[end] == '[') {
	        end = skipPredicate(match, end);
		if (end <= 0) {
		    xsltTransformError(NULL, style, inst,
		        "xsl:key : 'match' pattern is malformed: %s",
		        key->match);
		    if (style != NULL) style->errors++;
		    goto error;
		}
	    } else
		end++;
	}
	if (current == end) {
	    xsltTransformError(NULL, style, inst,
			       "xsl:key : 'match' pattern is empty\n");
	    if (style != NULL) style->errors++;
	    goto error;
	}
	if (match[start] != '/') {
	    pattern = xmlStrcat(pattern, (xmlChar *)"//");
	    if (pattern == NULL) {
		if (style != NULL) style->errors++;
		goto error;
	    }
	}
	pattern = xmlStrncat(pattern, &match[start], end - start);
	if (pattern == NULL) {
	    if (style != NULL) style->errors++;
	    goto error;
	}

	if (match[end] == '|') {
	    pattern = xmlStrcat(pattern, (xmlChar *)"|");
	    end++;
	}
	current = end;
    }
    if (pattern == NULL) {
        xsltTransformError(NULL, style, inst,
                           "xsl:key : 'match' pattern is empty\n");
        if (style != NULL) style->errors++;
        goto error;
    }
#ifdef WITH_XSLT_DEBUG_KEYS
    xsltGenericDebug(xsltGenericDebugContext,
	"   resulting pattern %s\n", pattern);
#endif
    /*
    * XSLT-1: "It is an error for the value of either the use
    *  attribute or the match attribute to contain a
    *  VariableReference."
    * TODO: We should report a variable-reference at compile-time.
    *   Maybe a search for "$", if it occurs outside of quotation
    *   marks, could be sufficient.
    */
#ifdef XML_XPATH_NOVAR
    key->comp = xsltXPathCompileFlags(style, pattern, XML_XPATH_NOVAR);
#else
    key->comp = xsltXPathCompile(style, pattern);
#endif
    if (key->comp == NULL) {
	xsltTransformError(NULL, style, inst,
		"xsl:key : 'match' pattern compilation failed '%s'\n",
		         pattern);
	if (style != NULL) style->errors++;
    }
#ifdef XML_XPATH_NOVAR
    key->usecomp = xsltXPathCompileFlags(style, use, XML_XPATH_NOVAR);
#else
    key->usecomp = xsltXPathCompile(style, use);
#endif
    if (key->usecomp == NULL) {
	xsltTransformError(NULL, style, inst,
		"xsl:key : 'use' expression compilation failed '%s'\n",
		         use);
	if (style != NULL) style->errors++;
    }

    /*
     * Sometimes the stylesheet writer use the order to ease the
     * resolution of keys when they are dependant, keep the provided
     * order so add the new one at the end.
     */
    if (style->keys == NULL) {
	style->keys = key;
    } else {
        xsltKeyDefPtr prev = style->keys;

	while (prev->next != NULL)
	    prev = prev->next;

	prev->next = key;
    }
    key->next = NULL;

error:
    if (pattern != NULL)
	xmlFree(pattern);
    return(0);
}
示例#14
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;	
}
示例#15
0
/**
 * xsltCompileAttr:
 * @style:  a XSLT process context
 * @attr: the attribute coming from the stylesheet.
 *
 * Precompile an attribute in a stylesheet, basically it checks if it is
 * an attrubute value template, and if yes establish some structures needed
 * to process it at transformation time.
 */
void
xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
    const xmlChar *str;
    const xmlChar *cur;
    xmlChar *ret = NULL;
    xmlChar *expr = NULL;
    xsltAttrVTPtr avt;
    int i = 0, lastavt = 0;

    if ((style == NULL) || (attr == NULL) || (attr->children == NULL))
        return;
    if ((attr->children->type != XML_TEXT_NODE) ||
        (attr->children->next != NULL)) {
        xsltTransformError(NULL, style, attr->parent,
	    "Attribute '%s': The content is expected to be a single text "
	    "node when compiling an AVT.\n", attr->name);
	style->errors++;
	return;
    }
    str = attr->children->content;
    if ((xmlStrchr(str, '{') == NULL) &&
        (xmlStrchr(str, '}') == NULL)) return;

#ifdef WITH_XSLT_DEBUG_AVT
    xsltGenericDebug(xsltGenericDebugContext,
		    "Found AVT %s: %s\n", attr->name, str);
#endif
    if (attr->psvi != NULL) {
#ifdef WITH_XSLT_DEBUG_AVT
	xsltGenericDebug(xsltGenericDebugContext,
			"AVT %s: already compiled\n", attr->name);
#endif
        return;
    }
    /*
    * Create a new AVT object.
    */
    avt = xsltNewAttrVT(style);
    if (avt == NULL)
	return;
    attr->psvi = avt;

    avt->nsList = xmlGetNsList(attr->doc, attr->parent);
    if (avt->nsList != NULL) {
	while (avt->nsList[i] != NULL)
	    i++;
    }
    avt->nsNr = i;

    cur = str;
    while (*cur != 0) {
	if (*cur == '{') {
	    if (*(cur+1) == '{') {	/* escaped '{' */
	        cur++;
		ret = xmlStrncat(ret, str, cur - str);
		cur++;
		str = cur;
		continue;
	    }
	    if (*(cur+1) == '}') {	/* skip empty AVT */
		ret = xmlStrncat(ret, str, cur - str);
	        cur += 2;
		str = cur;
		continue;
	    }
	    if ((ret != NULL) || (cur - str > 0)) {
		ret = xmlStrncat(ret, str, cur - str);
		str = cur;
		if (avt->nb_seg == 0)
		    avt->strstart = 1;
		if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
		    goto error;
		ret = NULL;
		lastavt = 0;
	    }

	    cur++;
	    while ((*cur != 0) && (*cur != '}')) {
		/* Need to check for literal (bug539741) */
		if ((*cur == '\'') || (*cur == '"')) {
		    char delim = *(cur++);
		    while ((*cur != 0) && (*cur != delim))
			cur++;
		    if (*cur != 0)
			cur++;	/* skip the ending delimiter */
		} else
		    cur++;
	    }
	    if (*cur == 0) {
	        xsltTransformError(NULL, style, attr->parent,
		     "Attribute '%s': The AVT has an unmatched '{'.\n",
		     attr->name);
		style->errors++;
		goto error;
	    }
	    str++;
	    expr = xmlStrndup(str, cur - str);
	    if (expr == NULL) {
		/*
		* TODO: What needs to be done here?
		*/
	        XSLT_TODO
		goto error;
	    } else {
		xmlXPathCompExprPtr comp;

		comp = xsltXPathCompile(style, expr);
		if (comp == NULL) {
		    xsltTransformError(NULL, style, attr->parent,
			 "Attribute '%s': Failed to compile the expression "
			 "'%s' in the AVT.\n", attr->name, expr);
		    style->errors++;
		    goto error;
		}
		if (avt->nb_seg == 0)
		    avt->strstart = 0;
		if (lastavt == 1) {
		    if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL)
		        goto error;
		}
		if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL)
		    goto error;
		lastavt = 1;
		xmlFree(expr);
		expr = NULL;
	    }
	    cur++;
	    str = cur;
	} else if (*cur == '}') {
示例#16
0
文件: xlibxml.c 项目: GNOME/gxml
/**
 * gxml_doc_get_ns_list:
 *
 * Deprecated: 0.15
 */
xmlNsPtr* gxml_doc_get_ns_list (xmlDoc* doc, xmlNode* node)
{
  g_return_val_if_fail (doc != NULL, NULL);
  g_return_val_if_fail (node != NULL, NULL);
  return xmlGetNsList (doc, node);
}