C - libxml2 - 更新XML元素值和属性

时间:2016-04-03 19:31:31

标签: c libxml2

我正在尝试使用C和libxml2库更新XML文档。 我想有选择地根据一些配置值更新XML元素和/或属性。

看起来我可以使用xmlSetProp来更新XML属性,但我看不出如何使用它来更新XML元素值。似乎在使用xmlSetProp时它会添加一个新属性,但我认为我可以通过先删除属性来解决这个问题。

请有人告诉我如何使用libxml2库来更新元素。为了给出一些上下文,我希望能够处理以下XML并更新值:

<person sex="female">
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person>

所以好像我可以使用xmlSetProp更新性别属性,但是如何更新名字的值呢?

提前感谢您的帮助。

在你们的帮助下,我写下了我需要的东西(下面)并希望它能使其他人受益。

由于

xmlXPathObjectPtr GetNodeSet(const xmlDocPtr pDoc, xmlChar* pszXPath)
{
    static const char szFctName[]= __FUNCTION__;
    xmlXPathContextPtr pContext = NULL;
    xmlXPathObjectPtr pResult = NULL;

    Debug("%s '%s'\n", szFctName, pszXPath);

    pContext = xmlXPathNewContext(pDoc);
    if (pContext == NULL) 
    {
        Debug("Error in xmlXPathNewContext pContext is NULL\n");
        return NULL;
    }
    pResult = xmlXPathEvalExpression(pszXPath, pContext);
    xmlXPathFreeContext(pContext);
    if (pResult == NULL) 
    {
        Debug("Error in xmlXPathEvalExpression pResult is NULL\n");
        return NULL;
    }
    if (xmlXPathNodeSetIsEmpty(pResult->nodesetval))
    {
        xmlXPathFreeObject(pResult);
        Debug("No results found\n");
        return NULL;
    }
    return pResult;
}

xmlDocPtr GetXMLDoc(char* pszXMLFilename)
{
    static const char szFctName[]= __FUNCTION__;
    xmlDocPtr pDoc = xmlParseFile(pszXMLFilename);

    Debug("%s '%s'\n", szFctName, pszXMLFilename);

    if (pDoc == NULL )
    {
        Debug("Document: '%s' not parsed successfully. \n", pszXMLFilename);
        return NULL;
    }

    return pDoc;
}

// Some code below (extracted and modified so won't compile purely for example) that is used to update the XML

// xmllib vars
xmlNodePtr pNode = NULL;
xmlDocPtr pDoc = NULL;
xmlNodeSetPtr pNodeSet = NULL;
xmlXPathObjectPtr pResult = NULL;


// Get the XML doc
pDoc = GetXMLDoc(pszXMLFilename);

// Using XPath to navigate to element.
pResult = GetNodeSet(pDoc, "/configuration/appSettings/add[@key='KeyToSearchFor']");


if (pResult && pResult->nodesetval)
{
    pNodeSet = pResult->nodesetval;
    for (iNodeSetValue = 0; iNodeSetValue < pNodeSet->nodeNr; iNodeSetValue++) 
    {
        if (pNodeSet->nodeTab)
        {
            pNode = pNodeSet->nodeTab[iNodeSetValue];

            if (pNode)
            {
                if (ItsAnElement /*I configured this*/)
                {
                    xmlNodeSetContent(pNode, szNewXMLValue);
                }
                else if (ItsAnAttribute /*I configured this*/)
                {
                    if (xmlGetProp(pNode, XML_ATTRIBUTE_NODE_VALUE_NAME))
                    {
                        xmlSetProp(pNode, BAD_CAST XML_ATTRIBUTE_NODE_VALUE_NAME, szNewXMLValue);
                    }
                    else
                    {
                        Debug("%s Couldn't find XML property value for: '%s'\n", szFctName, pParams[iTag].szXMLTagXPathValue);
                    }
                }
            }
        }
    }
}

// We're about to save our changes. Backup the file first and only update if this succeeds
if (BackupXMLFile(pszXMLFilename))
{
    // Returns: The number of bytes written or -1 in case of failure.
    if (xmlSaveFileEnc(pszXMLFilename, pDoc, "utf-8") >= 0)
    {
        iStatus = E_OK;
    }
    else
    {
        Debug("%s xmlSaveFileEnc failed\n", szFctName);
    }
}
else
{
    iStatus = E_ERR;
}

xmlFreeDoc(pDoc);

0 个答案:

没有答案