2017-01-26 48 views
2

libxml2ライブラリを使用するための小さなラッパーを作成しています。コンテンツが混在している場合は要素値を変更することに問題があります。libmxl2 - 要素が混在している値を変更する

次の例では、 "OLD CONTENT"値とサブチャイルド "child1.1"を持つ "child1"要素を作成しています。次に、xmlNodeSetContent関数(< ---とマークされた行)を使用して、 "child1"の値を "NEW CONTENT"に変更しようとしています。問題は、 "child1.1"がxmlNodeSetContentによって削除されていることです。私は値を "古いコンテンツ"から "新しいコンテンツ"に変更したいと思います。

xmlNodeSetContentは、これを行うには適切な機能ではないか、あるいはlibxml2に何かがあります。私はそれが欠けています。

質問:混在コンテンツの場合の値の変更方法はありますか?もしそうなら、それを行う方法?

#include <stdio.h> 
#include <string.h> 

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

#define MY_ENCODING "ISO-8859-1" 

xmlNodePtr createRoot(xmlDocPtr doc, char* name) 
{ 
    xmlNodePtr root; 
    root = xmlNewNode(NULL, BAD_CAST name); 
    xmlDocSetRootElement(doc, root); 
    return root; 
} 

xmlNodePtr addChild(xmlNodePtr parent, char* name, char* value) 
{ 
    return xmlNewChild(parent, NULL, BAD_CAST name, BAD_CAST value); 
} 

void setElementContent(xmlNodePtr element, char* value) 
{ 
    xmlNodeSetContent(element, BAD_CAST value); 
} 

void setElementAttribute(xmlNodePtr element, char* attribName, char* attribValue) 
{ 
    xmlSetProp(element, BAD_CAST attribName, BAD_CAST attribValue); 
} 

int main(int argc, char** argv) 
{ 
    xmlDocPtr doc = NULL; 
    xmlNodePtr root = NULL; 
    xmlNodePtr tmp1 = NULL; 
    xmlNodePtr tmp11 = NULL; 
    xmlNodePtr tmp2 = NULL; 

    xmlChar* xmlbuff; 
    int buffersize; 


    doc = xmlNewDoc(BAD_CAST "1.0"); 

    root = createRoot(doc, "root"); 

    //tmp1 = addChild(root, "child1", NULL); 
    tmp1 = addChild(root, "child1", "OLD CONTENT"); 

    tmp11 = addChild(tmp1, "child1.1", NULL); 
    setElementContent(tmp11, "blablabla"); 

    tmp2 = addChild(root, "child2", NULL); 
    setElementContent(tmp2, "22222"); 
    setElementAttribute(tmp2, "id", "002"); 
    setElementAttribute(tmp2, "lang", "en"); 

    setElementContent(tmp1, "NEW CONTENT"); // <--- 

    //xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); 
    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, MY_ENCODING, 1); 
    printf("%s", (char *) xmlbuff); 

    xmlCleanupParser(); 

    xmlFree(xmlbuff); 
    xmlFreeDoc(doc); 

    return 0; 
} 

EDIT:作業バージョン:

#include <stdio.h> 
#include <string.h> 

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

#define MY_ENCODING "ISO-8859-1" 

xmlNodePtr createRoot(xmlDocPtr doc, char* name) 
{ 
    xmlNodePtr root; 
    root = xmlNewNode(NULL, BAD_CAST name); 
    xmlDocSetRootElement(doc, root); 
    return root; 
} 

xmlNodePtr addChild(xmlNodePtr parent, char* name, char* value) 
{ 
    return xmlNewChild(parent, NULL, BAD_CAST name, BAD_CAST value); 
} 

void setElementContent(xmlNodePtr element, char* value) 
{ 
    xmlNodePtr it = NULL; 
    int bFound = 0; 

    for (it = element->children; it != NULL; it = it->next) 
    { 
     if (it->type == XML_TEXT_NODE) 
     { 
      xmlNodeSetContent(it, BAD_CAST value); 
      bFound = 1; 
     } 
    } 

    if (!bFound) 
    { 
     xmlNodeSetContent(element, BAD_CAST value); 
    } 
} 

void setElementAttribute(xmlNodePtr element, char* attribName, char* attribValue) 
{ 
    xmlSetProp(element, BAD_CAST attribName, BAD_CAST attribValue); 
} 

void printXml(xmlDocPtr doc) 
{ 
    xmlChar* xmlbuff; 
    int buffersize; 

    //xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); 
    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, MY_ENCODING, 1); 
    printf("%s", (char *) xmlbuff); 
    xmlCleanupParser(); 
    xmlFree(xmlbuff); 
} 

int main(int argc, char** argv) 
{ 
    xmlDocPtr doc = NULL; 
    xmlNodePtr root = NULL; 
    xmlNodePtr tmp1 = NULL; 
    xmlNodePtr tmp11 = NULL; 
    xmlNodePtr tmp2 = NULL; 
    xmlNodePtr tmp3 = NULL; 
    xmlNodePtr it = NULL; 

    doc = xmlNewDoc(BAD_CAST "1.0"); 

    root = createRoot(doc, "root"); 

    //tmp1 = addChild(root, "child1", NULL); 
    tmp1 = addChild(root, "child1", "OLD CONTENT"); 

    tmp11 = addChild(tmp1, "child1.1", NULL); 
    setElementContent(tmp11, "blablabla"); 

    tmp2 = addChild(root, "child2", NULL); 
    setElementContent(tmp2, "22222"); 
    setElementAttribute(tmp2, "id", "002"); 
    setElementAttribute(tmp2, "lang", "en"); 

    tmp3 = addChild(root, "child3", NULL); /* create empty */ 

    printf("\nBefore:\n"); 
    printXml(doc); 

    setElementContent(tmp1, "NEW CONTENT"); 
    setElementContent(tmp3, "333"); 

    printf("\nAfter:\n"); 
    printXml(doc); 

    xmlFreeDoc(doc); 

    return 0; 
} 

答えて

1

混合コンテンツは、テキストノードおよび要素ノードの配列によって表されます。テキストノードを取得して内容を置き換える必要があります:

xmlNodePtr textNode = &tmp1->children[0]; 
setElementContent(textNode, "NEW CONTENT"); 
//setElementContent(tmp1, "NEW CONTENT"); // <--- 
+1

ありがとうございます!これは適切な方法であるようです。私は新しいコードを質問に入れました。コンテンツを設定する機能がテキスト要素を検索し、見つかった場合は値を変更します。見つからなければ、新しい要素を置きます。 –

関連する問題