C 如何获取xmlHashTable的键?(libxml2)

C 如何获取xmlHashTable的键?(libxml2),c,hashtable,libxml2,C,Hashtable,Libxml2,我正在使用libxml2库解析XML文档。然后我在这个库中看到了xmlHashTable。是否可以获取xmlHashTable的所有键?我想将所有密钥存储在一个数组中 XML文档是: <?xml version="1.0" encoding="UTF-8"?> <?type-proto key="MIPRegistrationRequest" value="mip" ?> <?avp-proto key="Example-AVP" value="data" ?&g

我正在使用libxml2库解析XML文档。然后我在这个库中看到了
xmlHashTable
。是否可以获取
xmlHashTable
的所有键?我想将所有密钥存储在一个数组中

XML文档是:

<?xml version="1.0" encoding="UTF-8"?>

<?type-proto key="MIPRegistrationRequest" value="mip" ?>
<?avp-proto key="Example-AVP" value="data" ?>

<!DOCTYPE dictionary SYSTEM "dictionary.dtd" [
    <!-- Any files added here need to be added to Makefile.am and
         packaging/nsis/wireshark.nsi -->

    <!ENTITY nasreq         SYSTEM "nasreq.xml">
    <!ENTITY eap            SYSTEM "eap.xml">
    <!ENTITY mobileipv4     SYSTEM "mobileipv4.xml">
    <!ENTITY chargecontrol      SYSTEM "chargecontrol.xml">
    <!ENTITY sunping        SYSTEM "sunping.xml">
    <!ENTITY TGPP           SYSTEM "TGPP.xml">
    <!ENTITY TGPP2          SYSTEM "TGPP2.xml">
    <!ENTITY sip            SYSTEM "sip.xml">
    <!ENTITY etsie2e4       SYSTEM "etsie2e4.xml">
    <!ENTITY Ericsson       SYSTEM "Ericsson.xml">
    <!ENTITY mobileipv6     SYSTEM "mobileipv6.xml">
    <!ENTITY Cisco          SYSTEM "Cisco.xml">
    <!ENTITY Starent        SYSTEM "Starent.xml">
    <!ENTITY Vodafone       SYSTEM "Vodafone.xml">
    <!ENTITY AlcatelLucent      SYSTEM "AlcatelLucent.xml">
    <!ENTITY Nokia          SYSTEM "Nokia.xml">
    <!ENTITY NokiaSolutionsAndNetworks  SYSTEM "NokiaSolutionsAndNetworks.xml">
    <!ENTITY HP         SYSTEM "HP.xml">
    <!ENTITY Oracle         SYSTEM "Oracle.xml">
    <!ENTITY Custom         SYSTEM "Custom.xml">
]>
<dictionary>
...
<dictionary>

xmlentiestable
的类型是一个
xmlHashTable

有一个函数(及其更挑剔的亲戚),它可以用来让库为
xmlHashTable
中的每个条目回调一个用户提供的函数。
xmlHashScanner
将每个条目的
name
作为参数提供,因此,以这种方式组合所有密钥的列表应该很容易。

对于那些想了解更多详细信息(尤其是代码)的人,您可以查看我的以下代码,它可以帮助我获得密钥列表:

typedef struct _entities_key_list{
    xmlChar *name;
    struct _entities_key_list *next;
} entities_key_list;

static entities_key_list *head_key_list = NULL;
static entities_key_list *current_key_list = NULL;

/**
 * @brief Callback when scanning data in a hash with the simple scanner
 * @param the data in the hash
 * @param extra scanner data
 * @param the name associated
 * @return void
 */
void the_callback_function(void *payload, void *data, xmlChar *name){
    if(!head_key_list)
    {
        head_key_list = current_key_list = g_new(entities_key_list, 1);
        head_key_list->name = name;
        head_key_list->next = NULL;
    }
    else
    {
        current_key_list = current_key_list->next = g_new(entities_key_list, 1);
        current_key_list->name = name;
        current_key_list->next = NULL;
    }
}

/**
 * @brief Parses the entity inforamtion in the XML document: dictionary.xml
 * @param ptr pointer to an XML document
 * @return pointer to a linked list of type entity_t
 */
entity_t *parse_entities(xmlDocPtr ptr) 
{
    xmlHashScanner ptr27 = &the_callback_function;
    xmlHashTablePtr ptr28 = (xmlHashTablePtr) ptr->intSubset->entities;
    xmlHashScan(ptr28, ptr27, NULL);
    puts("**************************************************");
    puts("let's test if I have got the great result!");
    printf("the result is: %s\n", head_key_list->name);
    printf("the result is: %s\n", head_key_list->next->name);
    puts("**************************************************");
... //code that is not interesting anymore
}

你的问题很典型。获取实体声明的一种更简单的方法是迭代DTD节点的子节点:

xmlDtdPtr dtd = doc->intSubset;

for (xmlNodePtr child = dtd->children; child; child = child->next) {
    if (child->type == XML_ENTITY_DECL) {
        printf("%s\n", child->name);
    }
}

我添加了代码以显示我的问题。您能给我一些代码来帮助我获取密钥(例如,用户定义的xmlHashScanner的内容)吗?我已经为此苦苦挣扎了两个月,但从未找到解决方案。@BohaoLI:要给出一个权威的解决方案,我必须测试它。因为我只得到了您的代码片段,并且没有像我自己那样进行XML解析,所以我必须自己编写一个XML解析,当“放入”您更大的解决方案时,它可能是糟糕的体系结构。我帮不了你多少忙,可能会把你弄糊涂。除此之外,再过几个小时我就要去度假了,所以。。。。对不起-\没关系,玩得开心!事实上,你已经帮了我很多,因为从两个月前开始,我一直在想是否有可能做到这一点,现在我知道这是可能的,我将尝试自己找到答案。@BohaoLI:设置一个数据结构来保存关键列表。(数组、链表等)为
xmlHashScanner
设置具有所需配置文件的回调函数,该函数接受其
name
参数并将其添加到数据结构中。在
xmlentiestableptr
上调用
xmlHashScan
(如果我正确阅读了代码片段),将回调函数作为
xmlHashScanner
传递。就这样吧。
xmlDtdPtr dtd = doc->intSubset;

for (xmlNodePtr child = dtd->children; child; child = child->next) {
    if (child->type == XML_ENTITY_DECL) {
        printf("%s\n", child->name);
    }
}