簡體   English   中英

如何在libxml2中添加由string構造的xml節點

[英]How to add a xml node constructed from string in libxml2

我使用Libxml2來編碼xml文件中的數據。 我的數據包含“<”和“>”等標簽。 當它轉換為xml時,這些標簽也會轉換為“&lt”和“&gt”。 有沒有辦法解決這個問題。 我想在解碼那個xml文件時將這些標簽用作xml節點,因此CDATA不是解決此問題的方法。 請為此提供任何解決方案。 謝謝。

示例代碼:

xmlNewChild(node, NULL, (xmlChar *)"ADDRESS", (xmlChar *)"<street>Park Street</street><city>kolkata</city>");

and output of above code is:
<person>
<ADDRESS>&lt;street&gt;Park Street&lt;/street&gt;&lt;city&gt;Kolkata&lt;/city&gt;</ADDRESS>

如果您希望將字符串視為xml,則應使用xmlReadMemory解析它並從中獲取xmlDoc 它可用於較大的字符串,但通常使用單步指令構建文檔,如Joachim的答案。 在這里,我提出了xmlAddChildFromString函數來以字符串方式執行這些操作。

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

/// Returns 0 on failure, 1 otherwise
int xmlAddChildFromString(xmlNodePtr parent, xmlChar *newNodeStr)
{
  int rv = 0;
  xmlChar *newNodeStrWrapped = calloc(strlen(newNodeStr) + 10, 1);
  if (!newNodeStrWrapped) return 0;
  strcat(newNodeStrWrapped, "<a>");
  strcat(newNodeStrWrapped, newNodeStr);
  strcat(newNodeStrWrapped, "</a>");
  xmlDocPtr newDoc = xmlReadMemory(
    newNodeStrWrapped, strlen(newNodeStrWrapped),
    NULL, NULL, 0);
  free(newNodeStrWrapped);
  if (!newDoc) return 0;
  xmlNodePtr newNode = xmlDocCopyNode(
    xmlDocGetRootElement(newDoc),
    parent->doc,
    1);
  xmlFreeDoc(newDoc);
  if (!newNode) return 0;
  xmlNodePtr addedNode = xmlAddChildList(parent, newNode->children);
  if (!addedNode) {
    xmlFreeNode(newNode);
    return 0;
  }
  newNode->children = NULL; // Thanks to milaniez
  newNode->last = NULL;     // for fixing
  xmlFreeNode(newNode);     // the memory leak.
  return 1;
}

int
main(int argc, char **argv)
{
    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
    xmlNodePtr root = xmlNewNode(NULL, BAD_CAST "root");
    xmlDocSetRootElement(doc, root);
    xmlAddChildFromString(root,
      "<street>Park Street</street><city>kolkata</city>");
    xmlDocDump(stdout, doc);
    xmlFreeDoc(doc);
    return(0);
}

您必須在鏈中調用xmlNewChild ,一次調用父節點,並為每個子節點調用一次:

xmlNodePtr *addressNode = xmlNewChild(node, NULL, (xmlChar *) "address", NULL);
xmlNewChild(addressNode, NULL, (xmlChar *) "street", "Park Street");
xmlNewChild(addressNode, NULL, (xmlChar *) "city", "Koltaka");

您可以嘗試使用函數xmlParseInNodeContext。 它允許您在父節點的上下文中解析原始XML,並構造可以附加到父節點的節點。

例如:

const char * xml = "<a><b><c>blah</c></b></a>";
xmlNodePtr new_node = NULL;

// we assume that 'parent' node is already defined
xmlParseInNodeContext(parent, xml, strlen(xml), 0, &new_node);
if (new_node) xmlAddChild(parent, new_node);

我現在使用以下代碼將XML文本(可能包含多個元素)注入到現有節點中(感謝Nazar和nwellnhof的一個答案,並從我的問題中引用我( 將字符串注入到沒有內容轉義的XML節點中 )到這一個):

std::string xml = "<a>" + str + "</a>";
xmlNodePtr pNewNode = nullptr;
xmlParseInNodeContext(pParentNode, xml.c_str(), (int)xml.length(), 0, &pNewNode);
if (pNewNode != nullptr)
{
    // add new xml node children to parent
    xmlNode *pChild = pNewNode->children;
    while (pChild != nullptr)
    {
        xmlAddChild(pParentNode, xmlCopyNode(pChild, 1));
        pChild = pChild->next;
    }

    xmlFreeNode(pNewNode);
}

它需要字符串(str)添加一個周圍的元素( <a> ... <a /> ),使用xmlParseInNodeContext解析字符串,然后將新節點的子節點添加到父節點。 添加新節點的子節點而不是新節點非常重要,以避免在最終XML中使用<a> ... <a />。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM