如何使用libxmlc库获取XML中的属性?
某项任务要求我解析XML文件并检查每个节点及其属性。我花了几周时间学习XML和XML解析。我甚至还参考了先前发布的与C语言中LIBXML解析相关的问题,基于这种理解,我在下面编写了这段代码。但这段代码有缺陷,因为我没有达到目标 我想我搞乱了一些亲子和兄弟姐妹的观念。 我从下面提到的XML文件中了解到: Profile是根节点,Catalog是其子节点和 Catalog将子项作为参数和 参数将子项作为目标 所有目录节点都是彼此的兄弟节点如何使用libxmlc库获取XML中的属性?,c,xml,xml-parsing,libxml2,C,Xml,Xml Parsing,Libxml2,某项任务要求我解析XML文件并检查每个节点及其属性。我花了几周时间学习XML和XML解析。我甚至还参考了先前发布的与C语言中LIBXML解析相关的问题,基于这种理解,我在下面编写了这段代码。但这段代码有缺陷,因为我没有达到目标 我想我搞乱了一些亲子和兄弟姐妹的观念。 我从下面提到的XML文件中了解到: Profile是根节点,Catalog是其子节点和 Catalog将子项作为参数和 参数将子项作为目标 所有目录节点都是彼此的兄弟节点 Profile--> Catalog--> Pa
Profile--> Catalog--> Parameter-->Target
|-> Catalog--> Parameter-->Target
但是,当我试图通过将指针移动到Catalogs子节点指针来从一个目录转到另一个参数时,我无法转到。由于我无法达到参数,我无法到达目标
如能对我的理解和代码进行更正,将不胜感激。
另外,我的要求是用C语言编写代码,所以请不要告诉我其他语言
/***** MY XML FILE ***************************/
<?xml version="1.0" encoding="UTF-8"?>
<!-- When VIOS level changes, the value of ioslevel needs to change manually -->
<Profile origin="get" version="3.0.0" date="2012-10-05T00:00:00Z">
<Catalog1 id="devParam" version="3.0">
<Parameter1 name="policy" value="single" applyType="boot" reboot="true">
<Target1 class="device" instance="disk1"/>
</Parameter1>
</Catalog1>
<Catalog2 id="devParam" version="3.0">
<Parameter2 name="policy" value="no" applyType="boot">
<Target2 class="device" instance="disk2"/>
</Parameter2>
</Catalog2>
<Catalog3 id="devParam" version="3.0">
<Parameter3 name="policy" value="no" applyType="nextboot" reboot="true">
<Target3 class="device" instance="disk3"/>
</Parameter3>
</Catalog3>
</Profile>
/****************************************************************/
#include <string.h>
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
static void print_element_names(xmlDoc *doc, xmlNode * profile_node)
{
xmlNode *catalog_node = NULL, *parameter_node = NULL, *target_node = NULL, *tmp_node = NULL;
xmlChar *instance=NULL, *key=NULL;
if (xmlStrcmp(profile_node->name, (const xmlChar *) "Profile")) {
fprintf(stderr,"document of the wrong type, root node != story");
xmlFreeDoc(doc);
return;
}
for (catalog_node = profile_node->xmlChildrenNode; catalog_node; catalog_node =catalog_node->next)
{
if (catalog_node->type == XML_ELEMENT_NODE)
{
printf("Catalog %s \t type %d \n",catalog_node->name, catalog_node->type);
for(parameter_node = catalog_node->xmlChildrenNode; parameter_node; parameter_node = parameter_node->next)
{
if (parameter_node->type == XML_ELEMENT_NODE)
{
printf("Parameter %s \t type %d \n",parameter_node->name, parameter_node->type);
for( target_node=parameter_node->xmlChildrenNode->next; target_node; target_node=target_node->next)
{
printf("Target %s \t type %d \t",target_node->name, target_node->type);
if((target_node->type == XML_ELEMENT_NODE)&&(!strcmp(target_node->name, (const xmlChar *)"Target")))
{
instance_attr = xmlGetProp(inner_child, "instance");
printf("instance_attr = %s\n",instance_attr);
}
}
}
}
}
}
}
int main(int argc, char **argv)
{
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
if (argc != 2) return(1);
/*parse the file and get the DOM */
if ((doc = xmlReadFile(argv[1], NULL, 0)) == NULL){
printf("error: could not parse file %s\n", argv[1]);
exit(-1);
}
/*Get the root element node */
root_element = xmlDocGetRootElement(doc);
print_element_names(doc, root_element);
xmlFreeDoc(doc); /* free document*/
xmlCleanupParser(); /*/ Free globals*/
return 0;
}
/****我的XML文件***************************/
/****************************************************************/
#包括
#包括
#包括
#包括
静态无效打印元素名称(xmlDoc*doc,xmlNode*profile\u节点)
{
xmlNode*目录节点=NULL,*参数节点=NULL,*目标节点=NULL,*tmp节点=NULL;
xmlChar*instance=NULL,*key=NULL;
if(xmlStrcmp(profile_node->name,(const xmlChar*)“profile”)){
fprintf(stderr,“类型错误的文档,根节点!=故事”);
xmlFreeDoc(doc);
返回;
}
对于(目录节点=配置文件节点->xmlChildrenNode;目录节点;目录节点=目录节点->下一步)
{
if(目录\u节点->类型==XML\u元素\u节点)
{
printf(“目录%s\t类型%d\n”,目录节点->名称,目录节点->类型);
用于(参数\u节点=目录\u节点->xmlChildrenNode;参数\u节点;参数\u节点=参数\u节点->下一步)
{
if(参数\u节点->类型==XML\u元素\u节点)
{
printf(“参数%s\t类型%d\n”,参数\u节点->名称,参数\u节点->类型);
对于(目标节点=参数节点->xmlChildrenNode->下一步;目标节点;目标节点=目标节点->下一步)
{
printf(“目标%s\t类型%d\t”,目标节点->名称,目标节点->类型);
if((target\u node->type==XML\u ELEMENT\u node)&&(!strcmp(target\u node->name,(const xmlChar*)“target”))
{
instance_attr=xmlGetProp(内部子级,“实例”);
printf(“实例属性=%s\n”,实例属性);
}
}
}
}
}
}
}
int main(int argc,字符**argv)
{
xmlDoc*doc=NULL;
xmlNode*根元素=NULL;
如果(argc!=2)返回(1);
/*解析文件并获取DOM*/
if((doc=xmlReadFile(argv[1],NULL,0))==NULL){
printf(“错误:无法分析文件%s\n”,argv[1]);
出口(-1);
}
/*获取根元素节点*/
根元素=xmlDocGetRootElement(doc);
打印元素名称(文档、根元素);
xmlFreeDoc(doc);/*免费文档*/
xmlcleanuparser();/*/Free globals*/
返回0;
}
我最近对XML DOM的理解很好,它说元素的所有属性都在DOM中表示为该元素的子节点。因此,如果使用上述XML创建DOM,我们将看到:
Profile
___________________________|____________________
| | | | | |
date origin version catalog1 catalog2 catalog3
__________________________|
| | |
parameter version id
|_________________________________________
| | | | |
name value applytype reboot target
__________|
| |
instance class
目录2和目录3也将有他们的孩子。
基于这个DOM,如果我已经编写了get_next_node和get_children_node函数,它对我来说运行良好
/**
* get the children node and skip any non xml element node
*
* @param xml node
* @param xml children node
*
* @return xmlNodePtr children of xml node
*/
static void xmlGetNodeChildren(xmlNodePtr xmlNode, xmlNodePtr *childrenNode)
{
xmlNodePtr node = NULL;
node = xmlNode->children;
while (node->type != XML_ELEMENT_NODE)
{
node = node->next;
if (node == NULL)
{
break;
}
}
*childrenNode = node;
}
/**
* get the next node and skip any non xml element node
* such as text and comment node
*
* @param xml node
* @param xml next node
*/
static void xmlGetNodeNext(xmlNodePtr *xmlNode)
{
xmlNodePtr node = NULL;
node = (*xmlNode)->next;
while (node->type != XML_ELEMENT_NODE)
{
node=node->next;
if (node == NULL)
{
break;
}
}
*xmlNode = node;
}
为什么没有人回答?您可能需要使用
xmlFirstElementChild
和xmlNextElementSibling
。