[libxml2 xpath]如何使用字符串查询属性同时包含单引号和双引号 [英] [Libxml2 xpath] how to query a attribute with a string contains single quote and double quotation marks at same time

查看:121
本文介绍了[libxml2 xpath]如何使用字符串查询属性同时包含单引号和双引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

xml示例,lang属性同时包含单引号和双引号

 <?  xml     version   =  1.0    encoding   =  UTF-8  >  
< test >
< node lang = ' / >
< / test >





我的尝试:



我写了一个C程序,但它提示我

XPath错误:无效谓词

/ / node [@lang =''word']




  / *   
gcc -g`xml2-config --cflags` test.c`xml2-config --libs`
* /


#include < libxml / xmlmemory.h >
#include < libxml / parser.h >
#include < libxml / xpath.h >

#define XML_FILE_PATHtest.xml

int main( void
{
xmlDocPtr doc = NULL;
xmlXPathObjectPtr object = NULL;
xmlXPathContextPtr context = NULL;
xmlNodePtr curr = NULL;
xmlNodeSetPtr pNodeSet = NULL;
xmlChar * prop = NULL;
char lang [] = '\\ \\word;
char xpath [ 256 ];

doc = xmlParseFile(XML_FILE_PATH);
if (NULL == doc){
printf( xmlParseFile failed);
return - 1 ;
}
context = xmlXPathNewContext(doc);
if ( NULL == context){
printf( xmlXPathNewContext failed);
返回 - 1 ;
}

/ * 创建对象* /
snprintf(xpath, sizeof (XPA th), // node [@lang ='%s'],lang);
object = xmlXPathEvalExpression((xmlChar *)xpath,context);
xmlXPathFreeContext(context);
if (object == NULL){
printf( xmlXPathEvalExpression(%s)失败,xpath);
返回 - 1 ;
}

/ * NodeSet是空的? * /
if (xmlXPathNodeSetIsEmpty(object-> nodesetval)){
xmlXPathFreeObject(object);
printf( xmlXPathNodeSetIsEmpty);
return 0 ;
}

pNodeSet = object-> nodesetval;
curr = pNodeSet-> nodeTab [ 0 ];

prop = xmlGetProp(curr,(xmlChar *) lang) ;
printf( xmlGetProp%s,prop);
xmlFree(prop);
xmlXPathFreeObject(object);
xmlFreeDoc(doc);

return 0 ;
}

解决方案

您必须使用字符引用或实体( XML和HTML字符实体引用列表 - 维基百科 [ ^ ]。



在您的情况下,它将是:

 char lang [] =&& quot; word; 



您还可以编写一个函数来执行此操作:

 //或者使用boost :: replace_all 
void replace_all(std :: string& str,const std :: string& search,const std :: string& replace)
{
size_t len = search.length();
size_t pos = str.find(search);
while(std :: string :: npos!= npos)
{
str.replace(pos,len,replace);
pos = str.find(search,pos + len);
}
}

void Xmlify(std :: string& str)
{
replace_all(str,&,& amp; ;); //必须是第一个
replace_all(str,<,& lt;);
replace_all(str,>,& gt;);
replace_all(str,\,& quot;);
replace_all(str,',& quot;);
}


The xml example, the lang attribute contains single quote and double quotation marks at same time

<?xml version="1.0" encoding="UTF-8"?>
<test>
	<node lang="'"word" />
</test>



What I have tried:

I write a C program, but it prompt me that
XPath error : Invalid predicate
//node[@lang=''"word']


/*
gcc -g `xml2-config --cflags` test.c `xml2-config --libs`
*/

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>

#define XML_FILE_PATH "test.xml"

int main(void)
{
	xmlDocPtr doc = NULL;
	xmlXPathObjectPtr object = NULL;
	xmlXPathContextPtr context = NULL;
	xmlNodePtr curr = NULL;
	xmlNodeSetPtr pNodeSet = NULL;
	xmlChar* prop = NULL;
	char lang[] = "'\"word";
	char xpath[256];

	doc = xmlParseFile(XML_FILE_PATH);
	if (NULL == doc) {
		printf("xmlParseFile failed");
		return -1;
	}
	context = xmlXPathNewContext(doc);
	if (NULL == context) {
		printf("xmlXPathNewContext failed");
		return -1;
	}
	
	/* Create Object */
	snprintf(xpath, sizeof(xpath), "//node[@lang='%s']", lang);
	object = xmlXPathEvalExpression((xmlChar*)xpath, context);
	xmlXPathFreeContext(context);
	if (object == NULL) {
		printf("xmlXPathEvalExpression (%s) failed", xpath);
		return -1;
	}
	
	/* NodeSet Is Empty ? */
	if(xmlXPathNodeSetIsEmpty(object->nodesetval)) {
		xmlXPathFreeObject(object);
		printf("xmlXPathNodeSetIsEmpty");
		return 0;
	}

	pNodeSet = object->nodesetval;
	curr = pNodeSet->nodeTab[0];

	prop = xmlGetProp(curr, (xmlChar *)"lang");
	printf("xmlGetProp %s", prop);
	xmlFree(prop);
	xmlXPathFreeObject(object);
	xmlFreeDoc(doc);

	return 0;
}

解决方案

You have to use character references or entities (List of XML and HTML character entity references - Wikipedia[^]).

In your case it would be:

char lang[] = "&apos;&quot;word";


You can also write a function to do that:

// Or use boost::replace_all
void replace_all(std::string& str, const std::string& search, const std::string& replace)
{
    size_t len = search.length();
    size_t pos = str.find(search);
    while (std::string::npos != npos)
    {
        str.replace(pos, len, replace);
        pos = str.find(search, pos + len);
    }
}

void Xmlify(std::string& str)
{
    replace_all(str, "&", "&amp;"); // Must be the first
    replace_all(str, "<", "&lt;");
    replace_all(str, ">", "&gt;");
    replace_all(str, "\"", "&quot;");
    replace_all(str, "'", "&apos;");
}


这篇关于[libxml2 xpath]如何使用字符串查询属性同时包含单引号和双引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆