libxml2没有命名空间的复制节点或替换/删除命名空间

时间:2018-03-19 06:29:32

标签: xml libxml2

我有一些类似

的xml
<node xmlns="path/to/namespace">
  <grammar prop1="bla-bla-bla" prop2="etc">
    <!-- ... -->
  </grammar>
</node>

我希望获得语法标记,设置我的命名空间并保存所有属性(prop1,prop2),子节点等。 我只需要转到语法标记并调用xmlNodePtr copied = xmlCopyNode(node, 1);。 之后我删除了一些属性,添加了新的等等(复制后)。 之后,我想将名称空间"/path/to/namespace"替换为"/path/to/namespace2"。 没有像xmlRemoveNsxmlReplaceNs这样的功能,所以我只是释放命名空间并设置新的。

if (copied->ns)
{
  xmlFree((void*)copied->ns->href);
  copied->ns->href = xmlStrdup((const xmlChar *)"/path/to/namespace2");
}

但它看起来很奇怪而且有点可怕。 有没有办法替换命名空间,没有命名空间复制或删除命名空间并设置新的?

2 个答案:

答案 0 :(得分:1)

函数xmlFree()只释放某些库函数分配的内存,而不是你要搜索的内容。

尝试使用例如xmlSetNsProp()

xmlAttrPtr xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar * name, const xmlChar * value)
  

设置(或重置)节点承载的属性。 ns结构必须在范围内,不检查

     

节点:节点

     

ns:命名空间定义

     

name:属性名称

     

value:属性值

     

返回:属性指针。

您可以在此处找到更多信息:http://xmlsoft.org/html/libxml-tree.html 我认为你可以找到最适合你需要的功能。

在源代码中,命名空间似乎是ns->href

/**
 * xmlSetNsProp:
 * @node:  the node
 * @ns:  the namespace definition
 * @name:  the attribute name
 * @value:  the attribute value
 *
 * Set (or reset) an attribute carried by a node.
 * The ns structure must be in scope, this is not checked
 *
 * Returns the attribute pointer.
 */
xmlAttrPtr xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, const xmlChar *value)
    {
    xmlAttrPtr prop;

    if(ns && (ns->href == NULL))
        return (NULL);
    prop = xmlGetPropNodeInternal(node, name, (ns != NULL) ? ns->href : NULL, 0);
    if(prop != NULL)
        {
        /*
         * Modify the attribute's value.
         */
        if(prop->atype == XML_ATTRIBUTE_ID)
            {
            xmlRemoveID(node->doc, prop);
            prop->atype = XML_ATTRIBUTE_ID;
            }
        if(prop->children != NULL)
            xmlFreeNodeList(prop->children);
        prop->children = NULL;
        prop->last = NULL;
        prop->ns = ns;
        if(value != NULL)
            {
            xmlNodePtr tmp;

            if(!xmlCheckUTF8(value))
                {
                xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr)node->doc,
                NULL);
            if (node->doc != NULL)
            node->doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
            }
        prop->children = xmlNewDocText(node->doc, value);
        prop->last = NULL;
        tmp = prop->children;
        while(tmp != NULL)
            {
            tmp->parent = (xmlNodePtr)prop;
            if(tmp->next == NULL)
                prop->last = tmp;
            tmp = tmp->next;
            }
        }
    if(prop->atype == XML_ATTRIBUTE_ID)
        xmlAddID(NULL, node->doc, value, prop);
    return (prop);
    }
/*
 * No equal attr found; create a new one.
 */
return (xmlNewPropInternal(node, ns, name, value, 0));
}

答案 1 :(得分:0)

这似乎有效

xmlSetNs(copied, nullptr);