使用libxml2在现有XML中附加数据

时间:2018-01-12 10:50:36

标签: c xml libxml2

好吧,我正在尝试使用C编程和libxml2 modulel追加数据但面临很多问题,因为我对此很新。 我的代码旨在首先根据用户输入从XML文件中获取一个元素节点,然后抓取该子节点的父节点并在其中附加另一个子节点。

XML文件:

<a id="link1" href= "http://www.yahoo.com" onmouseover="this.style.background='#FFFF00'" onmouseout="this.style.background='#FFF'">this is a link</a>

C代码:

<policyList>
        <policySecurity>
                <policyName>AutoAdd</policyName>
                <deviceName>PA-722</deviceName>
                <status>ACTIVE</status>
                <srcZone>any</srcZone>
                <dstZone>any</dstZone>
                <srcAddr>5.5.5.5</srcAddr>
                <dstAddr>5.5.5.4</dstAddr>
                <srcUser>any</srcUser>
                <application>any</application>
                <service>htds</service>
                <urlCategory>any</urlCategory>
                <action>deny</action>
        </policySecurity>
        <policySecurity>
                <policyName>Test-1</policyName>
                <deviceName>PA-710</deviceName>
                <status>ACTIVE</status>
                <srcZone>any</srcZone>
                <dstZone>any</dstZone>
                <srcAddr>192.168.1.23</srcAddr>
                <dstAddr>8.8.8.8</dstAddr>
                <srcUser>vivek</srcUser>
                <application>any</application>
                <service>http</service>
                <urlCategory>any</urlCategory>
                <action>deny</action>
        </policySecurity>
</policyList>

在运行此代码时,它会被编译和执行(带有一些警告,但没有任何阻碍执行),但它不会向我的XML文件添加任何内容。

2 个答案:

答案 0 :(得分:1)

我认为这个话题很老,但是我也遇到了类似的问题。所以,我只是分享那些仍然有类似问题的人。

  

在运行此代码时,将对其进行编译和执行(带有一些警告,但没有任何阻碍执行的内容),但不会对我的XML文件添加任何内容。

首先:我认为C语言中的警告比错误严重得多,因为它使您可以运行错误的代码。因此,我的第一个建议是不要忽略这些警告(尽管无论如何我都不能给任何人提供建议)。

第二:当我运行这段代码时,我看到了一条有意义的警告:

> warning: passing argument 1 of ‘xmlAddSibling’ from incompatible
> pointer type [-Wincompatible-pointer-types]
> 
> note: expected ‘xmlNodePtr {aka struct _xmlNode *}’ but argument is of
> type ‘xmlXPathObjectPtr {aka struct _xmlXPathObject *}’

当您从http://www.xmlsoft.org/html/libxml-tree.html检查xmlAddSibling时,您会看到:

xmlNodePtr  xmlAddSibling       (xmlNodePtr cur, xmlNodePtr elem)

这意味着两个参数的类型都应为xmlNodePtr。但是,“结果”具有xmlXPathObjectPtr的类型,这意味着指针类型完全不同。您真正想要做的是根据比较的字符串(if(strcmp(keyword,srcaddr)== 0))向找到的父母添加一个孩子。

所以您找到父母的方式是完全正确的。但是有两个问题:首先,您从未更新过“结果”(如果我们假设您以为“结果”是不正确的父项),因为“ nodeset-> nodeTab [i]”处于for循环中,不会放置任何内容结果”。第二个问题是即使您基于“ nodeset-> nodeTab [i]”更新了“结果”,它们仍然具有不同类型的指针(如我们前面所讨论的)。因此,您必须为正确的父级和正确的指针类型使用xmlAddSibling。正如您在下面看到的那样,“ nodeTab”具有我们正在寻找的“ xmlNodePtr”类型,而“ nodeset-> nodeTab [i]”是父级。

Structure xmlNodeSet
struct _xmlNodeSet {
    int nodeNr  : number of nodes in the set
    int nodeMax : size of the array as allocated
    > `xmlNodePtr * nodeTab : array of nodes in no particular order`

}

所以您应该更改:

  

xmlAddSibling(result,pNode);

收件人:

  

xmlAddSibling(nodeset-> nodeTab [i],pNode);

最后:您没有保存更改。因此,通过添加

保存它
  

xmlSaveFileEnc(“ note.xml”,pDoc,“ UTF-8”);

之前

  

xmlFreeDoc(pDoc);

通过这些更改,我能够在没有警告的情况下使用XML文件运行您的代码。

答案 1 :(得分:0)

您的命令修改了内存中XML的DOM表示,但您错过了将其写回文件。因此,添加以下行应该可以解决您的问题:

   ...
}

// write back to file:
xmlSaveFileEnc("/var/www/db/db_policy.xml", pDoc, "UTF-8");

xmlFreeDoc(pDoc);
xmlCleanupParser();
return (1);