Exemple #1
0
BOOL GetMultipleNodeValueString(IXML_Node *pNode, char *pszName, char (*arrOutStr)[VCA5_APP_MAX_STR_LEN])
{
	BOOL ret = FALSE;
	IXML_NodeList *pTmpNodeList = ixmlElement_getElementsByTagName((IXML_Element*)pNode, pszName);
	if( pTmpNodeList ) {

		IXML_Node *pTmpNode = pTmpNodeList->nodeItem;
		IXML_Node *child  = ixmlNode_getFirstChild( pTmpNode );
		char *pszNodeValue = ixmlNode_getNodeValue( child );

		switch ( ixmlNode_getNodeType( child ) ) {

		case eTEXT_NODE:
			strcpy(arrOutStr[0], pszNodeValue);
			ret = TRUE;
			break;

		case eELEMENT_NODE:
		//	while() {
		//	}
		//	break;

		default:
			break;
		}

		ixmlNodeList_free(pTmpNodeList);
	}

	return ret;
}
char *SampleUtil_GetFirstElementItem(IXML_Element *element, const char *item)
{
	IXML_NodeList *nodeList = NULL;
	IXML_Node *textNode = NULL;
	IXML_Node *tmpNode = NULL;
	char *ret = NULL;

	nodeList = ixmlElement_getElementsByTagName(element, (char *)item);
	if (nodeList == NULL) {
		SampleUtil_Print("%s(%d): Error finding %s in XML Node\n",
			__FILE__, __LINE__, item);
		return NULL;
	}
	tmpNode = ixmlNodeList_item(nodeList, 0);
	if (!tmpNode) {
		SampleUtil_Print("%s(%d): Error finding %s value in XML Node\n",
			__FILE__, __LINE__, item);
		ixmlNodeList_free(nodeList);
		return NULL;
	}
	textNode = ixmlNode_getFirstChild(tmpNode);
	ret = strdup(ixmlNode_getNodeValue(textNode));
	if (!ret) {
		SampleUtil_Print("%s(%d): Error allocating memory for %s in XML Node\n",
			__FILE__, __LINE__, item);
		ixmlNodeList_free(nodeList);
		return NULL;
	}
	ixmlNodeList_free(nodeList);

	return ret;
}
Exemple #3
0
char *upnp_get_string(struct action_event *event, const char *key)
{
	IXML_Node *node;

	node = (IXML_Node *) event->request->ActionRequest;
	if (node == NULL) {
		upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS,
			       "Invalid action request document");
		return NULL;
	}
	node = ixmlNode_getFirstChild(node);
	if (node == NULL) {
		upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS,
			       "Invalid action request document");
		return NULL;
	}
	node = ixmlNode_getFirstChild(node);

	for (; node != NULL; node = ixmlNode_getNextSibling(node)) {
		if (strcmp(ixmlNode_getNodeName(node), key) == 0) {
			node = ixmlNode_getFirstChild(node);
			if (node == NULL) {
				/* Are we sure empty arguments are reported like this? */
				return strdup("");
			}
			return strdup(ixmlNode_getNodeValue(node));
		}
	}

	upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS,
		       "Missing action request argument (%s)", key);
	return NULL;
}
char *upnp_get_string(struct action_event *event, const char *key)
{
	IXML_Node *node;

	node = (IXML_Node *) event->request->ActionRequest;
	if (node == NULL) {
		upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS,
			       "Invalid action request document");
		return NULL;
	}
	node = ixmlNode_getFirstChild(node);
	if (node == NULL) {
		upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS,
			       "Invalid action request document");
		return NULL;
	}
	node = ixmlNode_getFirstChild(node);

	for (/**/; node != NULL; node = ixmlNode_getNextSibling(node)) {
		if (strcmp(ixmlNode_getNodeName(node), key) == 0) {
			node = ixmlNode_getFirstChild(node);
			const char *node_value = (node != NULL
						  ? ixmlNode_getNodeValue(node)
						  : NULL);
			return strdup(node_value != NULL ? node_value : "");
		}
	}

	upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS,
		       "Missing action request argument (%s)", key);
	return NULL;
}
Exemple #5
0
BOOL GetMultipleNodeValueInt(IXML_Node *pNode, char *pszName, int *arrOutint)
{
	BOOL ret = FALSE;
	IXML_NodeList *pTmpNodeList = ixmlElement_getElementsByTagName((IXML_Element*)pNode, pszName);
	if( pTmpNodeList ) {
		
		IXML_Node *pTmpNode = pTmpNodeList->nodeItem;
		IXML_Node *child  = ixmlNode_getFirstChild( pTmpNode );
		char *pszNodeValue = ixmlNode_getNodeValue( child );

		switch ( ixmlNode_getNodeType( child ) ) {

		case eTEXT_NODE:
			arrOutint[0] = atoi(pszNodeValue);
			ret = TRUE;
			break;

		case eELEMENT_NODE:
		//	while() {
		//	}
		//	break;

		default:
			break;
		}

		ixmlNodeList_free(pTmpNodeList);
	}

	return ret;
}
Exemple #6
0
/*
 * Extracts the result document from a SOAP response
 */
IXML_Document* parseBrowseResult( IXML_Document* p_doc )
{
    ixmlRelaxParser( 1 );

    if ( !p_doc ) return 0;

    IXML_NodeList* p_result_list = ixmlDocument_getElementsByTagName( p_doc,
                                                                   "Result" );

    if ( !p_result_list ) return 0;

    IXML_Node* p_result_node = ixmlNodeList_item( p_result_list, 0 );

    ixmlNodeList_free( p_result_list );

    if ( !p_result_node ) return 0;

    IXML_Node* p_text_node = ixmlNode_getFirstChild( p_result_node );
    if ( !p_text_node ) return 0;

    const char* psz_result_string = ixmlNode_getNodeValue( p_text_node );

    IXML_Document* p_browse_doc = ixmlParseBuffer( psz_result_string );

    return p_browse_doc;
}
char *upnp_igd_get_first_element_item(upnp_igd_context *igd_ctxt,IXML_Element *element, const char *item)
{
	IXML_NodeList *nodeList = NULL;
	IXML_Node *textNode = NULL;
	IXML_Node *tmpNode = NULL;
	char *ret = NULL;

	nodeList = ixmlElement_getElementsByTagName(element, (char *)item);
	if (nodeList == NULL) {
		upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "%s(%d): Error finding %s in XML Node",
			__FILE__, __LINE__, item);
		return NULL;
	}
	tmpNode = ixmlNodeList_item(nodeList, 0);
	if (!tmpNode) {
		upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "%s(%d): Error finding %s value in XML Node",
			__FILE__, __LINE__, item);
		ixmlNodeList_free(nodeList);
		return NULL;
	}
	textNode = ixmlNode_getFirstChild(tmpNode);
	ret = strdup(ixmlNode_getNodeValue(textNode));
	if (!ret) {
		upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "%s(%d): Error allocating memory for %s in XML Node",
			__FILE__, __LINE__, item);
		ixmlNodeList_free(nodeList);
		return NULL;
	}
	ixmlNodeList_free(nodeList);

	return ret;
}
Exemple #8
0
void printNodes(IXML_Node *tmpRoot, int depth)
{
    unsigned long i;
    IXML_NodeList *NodeList1;
    IXML_Node *ChildNode1;
    unsigned short NodeType;
    const DOMString NodeValue;
    const DOMString NodeName;
    NodeList1 = ixmlNode_getChildNodes(tmpRoot);
    for (i = 0; i < 100; ++i) {
        ChildNode1 = ixmlNodeList_item(NodeList1, i);
        if (ChildNode1 == NULL) {
            break;
        }
    
        printNodes(ChildNode1, depth+1);
        NodeType = ixmlNode_getNodeType(ChildNode1);
        NodeValue = ixmlNode_getNodeValue(ChildNode1);
        NodeName = ixmlNode_getNodeName(ChildNode1);
	IxmlPrintf(__FILE__, __LINE__, "printNodes",
            "DEPTH-%2d-IXML_Node Type %d, "
            "IXML_Node Name: %s, IXML_Node Value: %s\n",
            depth, NodeType, NodeName, NodeValue);
    }
}
Exemple #9
0
// Extracts the result document from a SOAP response
IXML_Document* parseBrowseResult( IXML_Document* doc )
{
    ixmlRelaxParser(1);

    if ( !doc ) return 0;

    IXML_NodeList* resultList = ixmlDocument_getElementsByTagName( doc,
                                                                   "Result" );

    if ( !resultList ) return 0;

    IXML_Node* resultNode = ixmlNodeList_item( resultList, 0 );

    ixmlNodeList_free( resultList );

    if ( !resultNode ) return 0;

    IXML_Node* textNode = ixmlNode_getFirstChild( resultNode );
    if ( !textNode ) return 0;

    const char* resultString = ixmlNode_getNodeValue( textNode );
    char* resultXML = strdup( resultString );

    IXML_Document* browseDoc = ixmlParseBuffer( resultXML );

    free( resultXML );

    return browseDoc;
}
char *get_node_value(struct xmlelement *element) {
	IXML_Node *node = (IXML_Node*) to_ielem(element);
	node = ixmlNode_getFirstChild(node);
	const char *node_value = (node != NULL
				  ? ixmlNode_getNodeValue(node)
				  : NULL);
	return strdup(node_value != NULL ? node_value : "");
}
Exemple #11
0
			v = (char*) ixmlNode_getNodeValue(l1_1_node);
			LoadConfigItem(Conf, sq_conf, n, v);
		}
		if (node_list) ixmlNodeList_free(node_list);
	}

	return node;
}

/*----------------------------------------------------------------------------*/
void *LoadConfig(char *name, tMRConfig *Conf, sq_dev_param_t *sq_conf)
{
	IXML_Element *elm;
	IXML_Document	*doc;

	doc = ixmlLoadDocument(name);
	if (!doc) return NULL;

	elm = ixmlDocument_getElementById(doc, "squeeze2upnp");
	if (elm) {
		unsigned i;
		char *n, *v;
		IXML_NodeList *l1_node_list;
		l1_node_list = ixmlNode_getChildNodes((IXML_Node*) elm);
		for (i = 0; i < ixmlNodeList_length(l1_node_list); i++) {
			IXML_Node *l1_node, *l1_1_node;
			l1_node = ixmlNodeList_item(l1_node_list, i);
			n = (char*) ixmlNode_getNodeName(l1_node);
			l1_1_node = ixmlNode_getFirstChild(l1_node);
			v = (char*) ixmlNode_getNodeValue(l1_1_node);
			LoadGlobalItem(n, v);
		}
		if (l1_node_list) ixmlNodeList_free(l1_node_list);
	}

	elm = ixmlDocument_getElementById((IXML_Document	*)elm, "common");
	if (elm) {
		char *n, *v;
		IXML_NodeList *l1_node_list;
		unsigned i;
		l1_node_list = ixmlNode_getChildNodes((IXML_Node*) elm);
		for (i = 0; i < ixmlNodeList_length(l1_node_list); i++) {
			IXML_Node *l1_node, *l1_1_node;
			l1_node = ixmlNodeList_item(l1_node_list, i);
char *SampleUtil_GetElementValue(IXML_Element *element)
{
	IXML_Node *child = ixmlNode_getFirstChild((IXML_Node *)element);
	char *temp = NULL;

	if (child != 0 && ixmlNode_getNodeType(child) == eTEXT_NODE)
		temp = strdup(ixmlNode_getNodeValue(child));

	return temp;
}
char *upnp_igd_get_element_value(upnp_igd_context *igd_ctxt, IXML_Element *element)
{
	IXML_Node *child = ixmlNode_getFirstChild((IXML_Node *)element);
	char *temp = NULL;

	if (child != 0 && ixmlNode_getNodeType(child) == eTEXT_NODE)
		temp = strdup(ixmlNode_getNodeValue(child));

	return temp;
}
Exemple #14
0
const char* xmldb_getMetaVariableValue(IXML_Element* obj, const char* name)
{
    IXML_Node* metaAttr = xmldb_getMetaVariable(obj, name);
    if (metaAttr == NULL)
    {
        return NULL;
    }

    return ixmlNode_getNodeValue(metaAttr);
}
Exemple #15
0
/* 
 * supported properties are:
 * deviceType
 * friendlyName
 * manufacturer
 * modelName
 * UDN
 * serviceType
 * serviceId
 **/
const char *get_device_property(IXML_Document *desc, const char *prop) {
    IXML_NodeList *list = ixmlDocument_getElementsByTagName(desc, prop);
    int length = ixmlNodeList_length(list);
    if (length < 1) {
        fprintf(stderr, "Error obtaining device name\n");
    }
    IXML_Node *n = ixmlNodeList_item(list, 0);
    n = ixmlNode_getFirstChild(n);
    return ixmlNode_getNodeValue(n);
}
Exemple #16
0
/****************************************************************************
*	Function :	get_var_name
*
*	Parameters :
*		IN IXML_Document *TempDoc :	Document containing variable request
*		OUT char* VarName :	Name of the state varible
*
*	Description :	This function finds the name of the state variable
*				asked in the SOAP request.
*
*	Return :	int
*		returns 0 if successful else returns -1.
*	Note :
****************************************************************************/
static UPNP_INLINE int
get_var_name( IN IXML_Document * TempDoc,
              OUT char *VarName )
{
    IXML_Node *EnvpNode = NULL;
    IXML_Node *BodyNode = NULL;
    IXML_Node *StNode = NULL;
    IXML_Node *VarNameNode = NULL;
    IXML_Node *VarNode = NULL;
    const DOMString StNodeName = NULL;
    const DOMString Temp = NULL;
    int ret_val = -1;

    // Got the Envelop node here
    EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc );
    if( EnvpNode == NULL ) {
        goto error_handler;
    }
    // Got Body here
    BodyNode = ixmlNode_getFirstChild( EnvpNode );
    if( BodyNode == NULL ) {
        goto error_handler;
    }
    // Got action node here
    StNode = ixmlNode_getFirstChild( BodyNode );
    if( StNode == NULL ) {
        goto error_handler;
    }
    //Test whether this is the action node
    StNodeName = ixmlNode_getNodeName( StNode );
    if( StNodeName == NULL || strstr( StNodeName,
                                      "QueryStateVariable" ) == NULL ) {
        goto error_handler;
    }

    VarNameNode = ixmlNode_getFirstChild( StNode );
    if( VarNameNode == NULL ) {
        goto error_handler;
    }

    VarNode = ixmlNode_getFirstChild( VarNameNode );
    Temp = ixmlNode_getNodeValue( VarNode );
    linecopy( VarName, Temp );

    UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
                "Received query for variable  name %s\n",
                VarName );

    ret_val = 0;            // success

error_handler:
    return ret_val;
}
Exemple #17
0
/************************************************************************
*	Function :	getElementValue
*
*	Parameters :
*		IXML_Node *node ;	Input node which provides the list of child 
*							nodes
*
*	Description :	Returns the clone of the element value
*
*	Return : DOMString ;
*
*	Note : value must be freed with DOMString_free
************************************************************************/
DOMString
getElementValue( IXML_Node * node )
{
    IXML_Node *child = ( IXML_Node * ) ixmlNode_getFirstChild( node );
    const DOMString temp = NULL;

    if( ( child != 0 ) && ( ixmlNode_getNodeType( child ) == eTEXT_NODE ) ) {
        temp = ixmlNode_getNodeValue( child );
        return ixmlCloneDOMString( temp );
    } else {
        return NULL;
    }
}
Exemple #18
0
/****************************************************************************
*	Function :	get_node_value
*
*	Parameters :
*			IN IXML_Node *node : input node	
*
*	Description :	This function returns the value of the text node
*
*	Return : DOMString
*		string containing the node value
*
*	Note :The given node must have a text node as its first child
****************************************************************************/
static const DOMString
get_node_value( IN IXML_Node * node )
{
    IXML_Node *text_node = NULL;
    const DOMString text_value = NULL;

    text_node = ixmlNode_getFirstChild( node );
    if( text_node == NULL ) {
        return NULL;
    }

    text_value = ixmlNode_getNodeValue( text_node );
    return text_value;
}
Exemple #19
0
const char*
XMLUtil_GetElementValue (IN const IXML_Element* element)
{
	char* res = NULL;
	IXML_Node* child = ixmlNode_getFirstChild 
		(discard_const_p (IXML_Node, XML_E2N (element)));
	while (child && !res) {
		if (ixmlNode_getNodeType (child) == eTEXT_NODE) {
		    // The resulting string should be copied if necessary
		    res = ixmlNode_getNodeValue (child);
		}
		child = ixmlNode_getNextSibling (child);
	}
	return res;
}
DOMString get_tag_string ( IXML_Node * node, 
                           char * tag )
{
    IXML_Node * temp = get_child_tag(node, tag);

    if ( temp ) {
        IXML_Node * text = ixmlNode_getFirstChild(temp);

        if ( text ) {
            return ixmlNode_getNodeValue(text);
        }
    }

    return NULL;
}
Exemple #21
0
const std::string CUPnPLib::Element_GetAttributeByTag(
	IXML_Element *element, const DOMString tag) const
{
	IXML_NamedNodeMap *NamedNodeMap = ixmlNode_getAttributes(
		REINTERPRET_CAST(IXML_Node *)(element));
	IXML_Node *attribute = ixmlNamedNodeMap_getNamedItem(NamedNodeMap, tag);
	const DOMString s = ixmlNode_getNodeValue(attribute);
	std::string ret;
	if (s) {
		ret = s;
	}
	ixmlNamedNodeMap_free(NamedNodeMap);

	return ret;
}
Exemple #22
0
static char *GetNodeAttributeByName(IXML_Node *node, char *name)
{
	IXML_NamedNodeMap *nnMap = NULL;
	IXML_Node *tmpNode = NULL;
	char *value = NULL;

	nnMap = ixmlNode_getAttributes(node);
	if(nnMap == NULL)
		return NULL;
	
	tmpNode = ixmlNamedNodeMap_getNamedItem(nnMap, name);
	if(tmpNode != NULL)
		value = ixmlNode_getNodeValue(tmpNode);
	ixmlNamedNodeMap_free(nnMap);
	return value;
}
Exemple #23
0
/*!
 * \brief Returns the TEXT node value of the current node.
 */
const std::string CUPnPLib::Element_GetTextValue(
	IXML_Element *element) const
{
	if (!element) {
		return stdEmptyString;
	}
	IXML_Node *text = ixmlNode_getFirstChild(
		REINTERPRET_CAST(IXML_Node *)(element));
	const DOMString s = ixmlNode_getNodeValue(text);
	std::string ret;
	if (s) {
		ret = s;
	}

	return ret;
}
Exemple #24
0
/*!
 * \brief Finds the name of the state variable asked in the SOAP request.
 *
 * \return 0 if successful else returns -1.
 */
static UPNP_INLINE int get_var_name(
	/*! [in] Document containing variable request. */
	IXML_Document *TempDoc,
	/*! [out] Name of the state varible. */
	char *VarName)
{
	IXML_Node *EnvpNode = NULL;
	IXML_Node *BodyNode = NULL;
	IXML_Node *StNode = NULL;
	IXML_Node *VarNameNode = NULL;
	IXML_Node *VarNode = NULL;
	const DOMString StNodeName = NULL;
	const DOMString Temp = NULL;
	int ret_val = -1;

	/* Got the Envelop node here */
	EnvpNode = ixmlNode_getFirstChild((IXML_Node *) TempDoc);
	if (EnvpNode == NULL)
		goto error_handler;
	/* Got Body here */
	BodyNode = ixmlNode_getFirstChild(EnvpNode);
	if (BodyNode == NULL)
		goto error_handler;
	/* Got action node here */
	StNode = ixmlNode_getFirstChild(BodyNode);
	if (StNode == NULL)
		goto error_handler;
	/* Test whether this is the action node */
	StNodeName = ixmlNode_getNodeName(StNode);
	if (StNodeName == NULL ||
	    strstr(StNodeName, "QueryStateVariable") == NULL)
		goto error_handler;
	VarNameNode = ixmlNode_getFirstChild(StNode);
	if (VarNameNode == NULL)
		goto error_handler;
	VarNode = ixmlNode_getFirstChild(VarNameNode);
	Temp = ixmlNode_getNodeValue(VarNode);
	linecopy(VarName, Temp);
	UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
		   "Received query for variable  name %s\n", VarName);

	/* success */
	ret_val = 0;

error_handler:
	return ret_val;
}
Exemple #25
0
int GetNodeValueInt(IXML_Node *pNode, char *pszName)
{
	assert( pNode != NULL && pszName != NULL );

	int nVal = -1;
	IXML_NodeList	*pTmpNodeList = NULL;
	pTmpNodeList = ixmlElement_getElementsByTagName((IXML_Element*)pNode, pszName);
	if(pTmpNodeList) {
		IXML_Node *n = pTmpNodeList->nodeItem;
		IXML_Node *child = ixmlNode_getFirstChild( n );
	//	printf("%s = %d\n", n->nodeName, atoi(ixmlNode_getNodeValue(child)));
		if( !child ) nVal = -1;
		else nVal = atoi(ixmlNode_getNodeValue(child));
		ixmlNodeList_free(pTmpNodeList);
	}
	return nVal;
}
Exemple #26
0
/*
 * Returns the value of a child element, or NULL on error
 */
const char* xml_getChildElementValue( IXML_Element* p_parent,
                                      const char*   psz_tag_name_ )
{
    if ( !p_parent ) return NULL;
    if ( !psz_tag_name_ ) return NULL;

    IXML_NodeList* p_node_list = ixmlElement_getElementsByTagName( p_parent, psz_tag_name_ );
    if ( !p_node_list ) return NULL;

    IXML_Node* p_element = ixmlNodeList_item( p_node_list, 0 );
    ixmlNodeList_free( p_node_list );
    if ( !p_element ) return NULL;

    IXML_Node* p_text_node = ixmlNode_getFirstChild( p_element );
    if ( !p_text_node ) return NULL;

    return ixmlNode_getNodeValue( p_text_node );
}
DOMString get_attribute_string ( IXML_Node * node, 
                                 char * name )
{
    IXML_Node * temp = node->firstAttr;
    DOMString value = NULL;

    while ( temp ) {
        if ( strcasecmp(temp->nodeName, name) == 0 ) {
            value = ixmlNode_getNodeValue(temp);
            break;
        }
        else {
            temp = temp->nextSibling;
        }
    }

    return value;
}
Exemple #28
0
static char *GetChildValueByName(IXML_Node *node, char *name)
{
	IXML_NodeList *nodeList = NULL;
	IXML_Node *textNode = NULL;
	IXML_Node *tmpNode = NULL;
	char *value = NULL;
	
	nodeList = ixmlElement_getElementsByTagName((IXML_Element*)node, name);
	if( nodeList != NULL ) {
		if((tmpNode = ixmlNodeList_item( nodeList, 0 )) != NULL) {
			if((textNode = ixmlNode_getFirstChild( tmpNode)) != NULL) {
				value = ixmlNode_getNodeValue(textNode);
			}
		}
		ixmlNodeList_free( nodeList );
	}
	return value;
}
Exemple #29
0
/*
 * Returns the value of a child element, or NULL on error
 */
const char* xml_getChildElementValue( IXML_Document*  p_doc,
                                      const char*     psz_tag_name )
{
    assert( p_doc );
    assert( psz_tag_name );

    IXML_NodeList* p_node_list;
    p_node_list = ixmlDocument_getElementsByTagName( p_doc, psz_tag_name );
    if ( !p_node_list )  return NULL;

    IXML_Node* p_element = ixmlNodeList_item( p_node_list, 0 );
    ixmlNodeList_free( p_node_list );
    if ( !p_element )    return NULL;

    IXML_Node* p_text_node = ixmlNode_getFirstChild( p_element );
    if ( !p_text_node )  return NULL;

    return ixmlNode_getNodeValue( p_text_node );
}
Exemple #30
0
// Returns the value of a child element, or 0 on error
const char* xml_getChildElementValue( IXML_Element* parent,
                                      const char*   tagName )
{
    if ( !parent ) return 0;
    if ( !tagName ) return 0;

    char* s = strdup( tagName );
    IXML_NodeList* nodeList = ixmlElement_getElementsByTagName( parent, s );
    free( s );
    if ( !nodeList ) return 0;

    IXML_Node* element = ixmlNodeList_item( nodeList, 0 );
    ixmlNodeList_free( nodeList );
    if ( !element ) return 0;

    IXML_Node* textNode = ixmlNode_getFirstChild( element );
    if ( !textNode ) return 0;

    return ixmlNode_getNodeValue( textNode );
}