libxml2的xpath检索中文

ZC: xmlXPathEvalExpression(...) 当 xpath的字符串中 包含中文的时候,返回NULL,暂时不知道该怎么处理了...

ZC: 下面是测试的一些代码/文件,留着以后再研究吧...

 

1、Qt5.3.2

2、XML 的节点的属性中包含中文(XML保存成 UTF-8的格式)

<?xml version="1.0" encoding="utf-8" ?>
<root>
    
    <newNode2>content changed</newNode2>
    <newNode3 newAttr="YES">newNode3 content</newNode3>
    <ceshi attribute="测试">测试一下</ceshi>
    <node2 attribute="no">NODE CONTENT</node2>
    
    <son>
        <grandson>This is a grandson node</grandson>
    <newGrandSon>new content</newGrandSon></son>
</root>

 

3、测试代码:

  ZC: 尝试了 使用 UTF-8的字符串、本地编码格式的字符串,都解析不到 我要的节点...

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
//#include <iconv.h>

#include <QDebug>
#include <QTextCodec>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}





int code_convert(char* from_charset, char* to_charset, char* inbuf,
               int inlen, char* outbuf, int outlen)
{
    iconv_t cd;
    char** pin = &inbuf;
    char** pout = &outbuf;
    cd = iconv_open(to_charset,from_charset);
    if(cd == 0)
       return -1;
    memset(outbuf,0,outlen);
    if(iconv(cd,(const char**)pin,(unsigned int *)&inlen,pout,(unsigned int*)&outlen)
       == -1)
       return -1;
    iconv_close(cd);
    return 0;
}

//UNICODE码转为GB2312码
//成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL
char* u2g(char *inbuf)
{
    int nOutLen = 2 * strlen(inbuf) - 1;
    char* szOut = (char*)malloc(nOutLen);
    if (-1 == code_convert("utf-8","gb2312",inbuf,strlen(inbuf),szOut,nOutLen))
    {
       free(szOut);
       szOut = NULL;
    }
    return szOut;
}

//GB2312码转为UNICODE码
//成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL
char* g2u(char *inbuf)
{
    int nOutLen = 2 * strlen(inbuf) - 1;
    char* szOut = (char*)malloc(nOutLen);
    if (-1 == code_convert("gb2312","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))
    {
       free(szOut);
       szOut = NULL;
    }
    return szOut;
}

xmlXPathObject* Get_NodeSet(xmlDoc* _pDoc, const xmlChar *szXpath)
{
    xmlXPathContextPtr context;
    xmlXPathObjectPtr result;

    context = xmlXPathNewContext(_pDoc);
    if (context == NULL)
    {
        //printf("context is NULL\n");
        return NULL;
    }

    result = xmlXPathEvalExpression(szXpath, context);
    xmlXPathFreeContext(context);
    if (result == NULL)
    {
        //printf("xmlXPathEvalExpression return NULL\n");
        return NULL;
    }

    if (xmlXPathNodeSetIsEmpty(result->nodesetval))
    {
        xmlXPathFreeObject(result);
        //printf("nodeset is empty\n");
        return NULL;
    }

    return result;
}

void MainWindow::on_pbtnXPath_clicked()
{
    xmlDocPtr doc = NULL;             //定义解析文档指针
    xmlNodePtr curNode = NULL;         //定义结点指针(你需要它为了在各个结点间移动)

    char *szDocName = "F:/ZZ_Qt5/Qt532_vs2010/build-libxml2_zz-z-Debug/debug/ChangedXml.xml";

    doc = xmlReadFile(szDocName, "GB2312", XML_PARSE_RECOVER);  //解析文件
    //doc = xmlReadFile(szDocName, "UTF-8", XML_PARSE_RECOVER);

    if (NULL == doc)
    {
        qDebug() << "Document not parsed successfully.";
        return;
    }

    char* pcCeShi = "测试";
    QTextCodec *pCodec = QTextCodec::codecForName("GBK");
    QString strCeShi = pCodec->toUnicode(pcCeShi);

    //QString str = "/root/node2[@attribute='no']";
    QString str = "/root/node2[@attribute='"+strCeShi+"']";
    QByteArray ba = str.toUtf8();
    //QByteArray ba = str.toLocal8Bit();
    char pc[256] = {0};
    memcpy(&pc[0], ba.data(), ba.length());
    //pc[ba.length()] = '\0';

    char *p0 = "/root/node2[@attribute='测试']";
    char* p1 = g2u(p0);
    char pc1[256] = {0};
    memcpy(&pc1[0], p1, strlen(p1));

    //xmlChar *szXpath =BAD_CAST ("/root/node2[@attribute='no']");
    xmlChar *szXpath = BAD_CAST (p1);
    xmlXPathObjectPtr app_result = Get_NodeSet(doc, szXpath);  //查询并得到结果

    if (NULL == app_result)
    {
        qDebug() << "app_result is NULL";
        return;
    }
    xmlChar *szValue = NULL;
    if(app_result)
    {
        xmlNodeSetPtr nodeset = app_result->nodesetval;
        for (int i = 0; i < nodeset->nodeNr; i++)
        {
            curNode = nodeset->nodeTab[i];
            if(curNode != NULL)
            {
                szValue = xmlGetProp(curNode,BAD_CAST "attribute");
                if (szValue != NULL)
                {
                    qDebug() << "attribute = " << (char*)szValue;
                    xmlFree(szValue);
                }

                szValue = xmlNodeGetContent(curNode);
                if (szValue != NULL)
                {
                    qDebug() << "content = " << (char*)szValue;
                    xmlFree(szValue);
                }
            }
        }
        xmlXPathFreeObject (app_result);
    }
    xmlFreeDoc(doc);

    free(p1);
}

 

4、

5、

6、

 

转载于:https://www.cnblogs.com/cppskill/p/7919995.html

可以使用libxml2库的xpath功能来修改节点的值。以下是一个示例代码: ```c #include <stdio.h> #include <libxml/parser.h> #include <libxml/xpath.h> int main(void) { xmlDocPtr doc; xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; xmlNodePtr node; const xmlChar *xpathExpr = (const xmlChar *)"//book[author='Charles Dickens']/title"; const xmlChar *new_value = (const xmlChar *)"A Tale of Two Cities"; // Load the XML document doc = xmlReadFile("books.xml", NULL, 0); if (doc == NULL) { fprintf(stderr, "Failed to parse document\n"); return 1; } // Create an XPath context xpathCtx = xmlXPathNewContext(doc); if (xpathCtx == NULL) { fprintf(stderr, "Failed to create XPath context\n"); xmlFreeDoc(doc); return 1; } // Evaluate the XPath expression xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); if (xpathObj == NULL) { fprintf(stderr, "Failed to evaluate XPath expression\n"); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return 1; } // Get the first matching node node = xpathObj->nodesetval->nodeTab[0]; // Change the node value xmlNodeSetContent(node, new_value); // Save the modified document if (xmlSaveFile("books.xml", doc) < 0) { fprintf(stderr, "Failed to save document\n"); xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return 1; } // Cleanup xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return 0; } ``` 这个示例代码会在books.xml文件中找到作者为Charles Dickens的书的标题,并将其修改为"A Tale of Two Cities"。要使用此代码,需要将books.xml文件放在与代码相同的目录下,并且需要链接libxml2库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值