以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XQuery/XLink/XPointer/ 』  (http://bbs.xml.org.cn/list.asp?boardid=14)
----  请问:怎么修改xml文件里面,node的element的内容  (http://bbs.xml.org.cn/dispbbs.asp?boardid=14&rootid=&id=24235)


--  作者:wispx
--  发布时间:11/14/2005 4:26:00 PM

--  请问:怎么修改xml文件里面,node的element的内容
想用C写一个小程序,来修改指定节点的元素的内容,在网上查到如下代码:
========================================


/**
* section:  XPath
* synopsis:  Load a document, locate subelements with XPath, modify
*              said elements and save the resulting document.
* purpose:  Shows how to make a full round-trip from a load/edit/save
* usage: xpath2 <xml-file> <xpath-expr> <new-value>
* test: xpath2 test3.xml '//discarded' discarded > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp
* author:  Aleksey Sanin and Daniel Veillard
* copy:  see Copyright for the status of this software.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

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

static void usage(const char *name);
static int example4(const char *filename, const xmlChar * xpathExpr,
                    const xmlChar * value);
static void update_xpath_nodes(xmlNodeSetPtr nodes, const xmlChar * value);


int
main(int argc, char **argv) {
    /* Parse command line and process file */
    if (argc != 4) {
 fprintf(stderr, "Error: wrong number of arguments.\n");
 usage(argv[0]);
 return(-1);
    }
    
    /* Init libxml */     
    xmlInitParser();
    LIBXML_TEST_VERSION

    /* Do the main job */
    if (example4(argv[1], BAD_CAST argv[2], BAD_CAST argv[3])) {
 usage(argv[0]);
 return(-1);
    }

    /* Shutdown libxml */
    xmlCleanupParser();
    
    /*
     * this is to debug memory for regression tests
     */
    xmlMemoryDump();
    return 0;
}

/**
* usage:
* @name:  the program name.
*
* Prints usage information.
*/
static void
usage(const char *name) {
    assert(name);
    
    fprintf(stderr, "Usage: %s <xml-file> <xpath-expr> <value>\n", name);
}

/**
* example4:
* @filename:  the input XML filename.
* @xpathExpr:  the xpath expression for evaluation.
* @value:  the new node content.
*
* Parses input XML file, evaluates XPath expression and update the nodes
* then print the result.
*
* Returns 0 on success and a negative value otherwise.
*/
static int
example4(const char* filename, const xmlChar* xpathExpr, const xmlChar* value) {
    xmlDocPtr doc;
    xmlXPathContextPtr xpathCtx;
    xmlXPathObjectPtr xpathObj;
    
    assert(filename);
    assert(xpathExpr);
    assert(value);

    /* Load XML document */
    doc = xmlParseFile(filename);
    if (doc == NULL) {
 fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
 return(-1);
    }

    /* Create xpath evaluation context */
    xpathCtx = xmlXPathNewContext(doc);
    if(xpathCtx == NULL) {
        fprintf(stderr,"Error: unable to create new XPath context\n");
        xmlFreeDoc(doc);
        return(-1);
    }
    
    /* Evaluate xpath expression */
    xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
    if(xpathObj == NULL) {
        fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(doc);
        return(-1);
    }

    /* update selected nodes */
    update_xpath_nodes(xpathObj->nodesetval, value);

    
    /* Cleanup of XPath data */
    xmlXPathFreeObject(xpathObj);
    xmlXPathFreeContext(xpathCtx);

    /* dump the resulting document */
    xmlDocDump(stdout, doc);


    /* free the document */
    xmlFreeDoc(doc);
    
    return(0);
}

/**
* update_xpath_nodes:
* @nodes:  the nodes set.
* @value:  the new value for the node(s)
*
* Prints the @nodes content to @output.
*/
static void
update_xpath_nodes(xmlNodeSetPtr nodes, const xmlChar* value) {
    int size;
    int i;
    
    assert(value);
    size = (nodes) ? nodes->nodeNr : 0;
    
    /*
     * NOTE: the nodes are processed in reverse order, i.e. reverse document
     *       order because xmlNodeSetContent can actually free up descendant
     *       of the node and such nodes may have been selected too ! Handling
     *       in reverse order ensure that descendant are accessed first, before
     *       they get removed. Mixing XPath and modifications on a tree must be
     *       done carefully !
     */
    for(i = size - 1; i >= 0; i--) {
 assert(nodes->nodeTab[i]);
 
 xmlNodeSetContent(nodes->nodeTab[i], value);
 /*
  * All the elements returned by an XPath query are pointers to
  * elements from the tree *except* namespace nodes where the XPath
  * semantic is different from the implementation in libxml2 tree.
  * As a result when a returned node set is freed when
  * xmlXPathFreeObject() is called, that routine must check the
  * element type. But node from the returned set may have been removed
  * by xmlNodeSetContent() resulting in access to freed data.
  * This can be exercised by running
  *       valgrind xpath2 test3.xml '//discarded' discarded
  * There is 2 ways around it:
  *   - make a copy of the pointers to the nodes from the result set
  *     then call xmlXPathFreeObject() and then modify the nodes
  * or
  *   - remove the reference to the modified nodes from the node set
  *     as they are processed, if they are not namespace nodes.
  */
 if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
     nodes->nodeTab[i] = NULL;
    }
}

========================================

但是里面的example4的update 好像没有工作,有朋友能帮帮我吗?


--  作者:wispx
--  发布时间:11/15/2005 9:51:00 AM

--  
搞了3天啦,还是没有搞定啊~~!
--  作者:wispx
--  发布时间:11/15/2005 9:59:00 AM

--  
大侠救救我 吧,查不出来错误所在啊。。!
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
62.500ms