C语言操作XML--libxml2---001

学生信息管理系统

这是我们老师的一个大作业,要求如下:

综合训练项目一 线性结构综合训练                          

目的和要求:线性结构是最基础,也是最重要的一种结构,通过此项训练让学生掌握线性结构的知识;要求编程实现学生成绩管理系统,使学生掌握线性结构的存储 及相关算法设计;设有一个学生文件,其结构为:学号、姓名、数学成绩、英语成绩、计算机成绩、总分、平均分、排名。要求用顺序和链式两种方式进行存储,并 在此基础上实现学生成绩的录入、保存、计算总分和平均分、排名、查询、统计等基本功能。

我最初的代码在:http://my.oschina.net/iamhere/blog/340999

而我现在写的带libxml2的代码如下:

test.c//程序入口,目前只是测试libxml2的部分

#include<stdio.h>
#include"stuxml.h"
#include"studentList.h"


int main( void ) {
    SL stulist = list_create_file( "student.txt" );
    list_print( stulist );
    man_create_list( stulist, "student.info.xml");
    
    
    
    return 0;
}


student.h//学生结构及其操作定义

/**
 * @file student.h
 * 定义了保存学生信息的结构体\n
 * 操作学生信息的函数:
 * 
 * 
 * 
 * @author 小代码
 */
#ifndef STUDENT_H_
#define STUDENT_H_
#include<stdbool.h>
/**
 * @brief 学生对象结构体定义
 */
struct student {
 /** @brief 学号 */
 int stu_id;
 /** @brief 姓名*/
 char stu_name[10];
 /** @brief 数学成绩 */
 double stu_score_math;
 /** @brief 英语成绩 */
 double stu_score_english;
 /** @brief 计算机成绩 */
 double stu_score_computer;
 /** @brief 总成绩*/
 double stu_score_sum;
 /** @brief 平均成绩 */
 double stu_score_avg;
 /** @brief 排名 */
 int stu_score_grade;
 /** @brief 直接前驱元素指针 */
 struct student * prev;
 /** @brief 直接后继元素指针 */
 struct student * next;
};
/** @brief 学生结构体 */
typedef struct student STU;
/** @brief 学生结构体指针 */
typedef struct student * Stu;
/**
 * @brief 输出学生信息的标题
 */
void print_title();
  
/**
 * @brief 创建一个学生信息对象
 * 
 * @param stu_id 学号
 * @param stu_name 姓名
 * @param stu_score_math 数学成绩
 * @param stu_score_english 英语成绩
 * @param stu_score_computer 计算机成绩
 * 
 * @return 指向学生对象结构体的指针
 * @retval NULL 创建失败
 */
Stu stu_create(int stu_id, char stu_name[20], double stu_score_math,
  double stu_score_english, double stu_score_computer);
/**
 * @brief 输出一个学生的信息
 * 
 * 输出格式为每项占10个空格\n
 * 如果参数为空,则不输出任何内容
 * 
 * @param stu 要输出信息的学生对象
 */
void stu_print(Stu stu);
/**
 * @brief 比较两个学生的平均分
 * 
 * 
 * @param stu1
 * @param stu2
 * 
 * @return 比较结果
 * @retval 1 stu1->stu_score_avg > stu2->stu_score_avg
 * @retval 0 stu1->stu_score_avg = stu2->stu_score_avg
 * @retval -1 stu1->stu_score_avg < stu2->stu_score_avg
 */
int stu_score_compare(Stu stu1, Stu stu2);
 
/**
 * @brief 交换两个学生对象的所有成员的值
 * 
 * 交换成功则返回 0\n
 * 如果有任何一个参数为 NULL ,则返回-1
 * 
 * @param stu1
 * @param stu2
 * 
 * @retval 0 交换成功
 * @retval -1 交换失败
 */
int stu_swap(Stu stu1, Stu stu2);
#endif /* STUDENT_H_ */

student.c//学生操作实现

#include"student.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/**
 * @brief 输出学生信息的标题
 */
void print_title() {
    printf("%-10s", "学号");
    printf("%-10s", "姓名");
    printf("%-10s", "数学");
    printf("%-10s", "英语");
    printf("%-10s", "计算机");
    printf("%-10s", "总分");
    printf("%-10s", "平均分");
    printf("%-10s\n", "排名");
}
/**
 * @brief 创建一个学生信息对象
 * 
 * @param stu_id 学号
 * @param stu_name 姓名
 * @param stu_score_math 数学成绩
 * @param stu_score_english 英语成绩
 * @param stu_score_computer 计算机成绩
 * 
 * @return 指向学生对象结构体的指针
 * @retval NULL 创建失败
 */
Stu stu_create(int stu_id, char stu_name[10], double stu_score_math,
        double stu_score_english, double stu_score_computer) {
    Stu stu = (Stu) malloc(sizeof(STU));
    if ( NULL == stu) {
        printf("stu_create...动态分配内存失败!");
        exit(-1);
    }
    stu->stu_id = stu_id;
    strcpy(stu->stu_name, stu_name);
    stu->stu_score_math = stu_score_math;
    stu->stu_score_english = stu_score_english;
    stu->stu_score_computer = stu_score_computer;
    stu->stu_score_sum = stu->stu_score_math + stu->stu_score_english
            + stu->stu_score_computer;
    stu->stu_score_avg = stu->stu_score_sum / 3;
    stu->stu_score_grade = -1;
    stu->prev = NULL;
    stu->next = NULL;
    return stu;
}
/**
 * @brief 输出一个学生的信息
 * 
 * 输出格式为每项占10个空格\n
 * 如果参数为空,则不输出任何内容
 * 
 * @param stu 要输出信息的学生对象
 */
void stu_print(Stu stu) {
    if ( NULL == stu) {
        return;
    }
    printf("%-10d", stu->stu_id);
    printf("%-10s", stu->stu_name);
    printf("%-10.2f", stu->stu_score_math);
    printf("%-10.2f", stu->stu_score_english);
    printf("%-10.2f", stu->stu_score_computer);
    printf("%-10.2f", stu->stu_score_sum);
    printf("%-10.2f", stu->stu_score_avg);
    printf("%-10d", stu->stu_score_grade);
    putchar('\n');
}
/**
 * @brief 比较两个学生的平均分
 * 
 * 
 * @param stu1
 * @param stu2
 * 
 * @return 比较结果
 * @retval 1 stu1->stu_score_avg > stu2->stu_score_avg
 * @retval 0 stu1->stu_score_avg = stu2->stu_score_avg
 * @retval -1 stu1->stu_score_avg < stu2->stu_score_avg
 */
int stu_score_compare(Stu stu1, Stu stu2) {
    int result = 0;
    if (stu1->stu_score_sum > stu2->stu_score_sum)
        result = 1;
    if (stu1->stu_score_sum < stu2->stu_score_sum)
        result = -1;
    return result;
}

/**
 * @brief 交换两个学生对象的所有成员的值
 * 
 * 交换成功则返回 0\n
 * 如果有任何一个参数为 NULL ,则返回-1
 * 
 * @param stu1
 * @param stu2
 * 
 * @retval 0 交换成功
 * @retval -1 交换失败
 */
int stu_swap(Stu stu1, Stu stu2) {
    if ( NULL == stu1 || NULL == stu2) {
        return -1;
    }
    int id_tmp = stu1->stu_id;
    stu1->stu_id = stu2->stu_id;
    stu2->stu_id = id_tmp;
    char name_tmp[10];
    strcpy(name_tmp, stu1->stu_name);
    strcpy(stu1->stu_name, stu2->stu_name);
    strcpy(stu2->stu_name, name_tmp);
    double score_tmp = stu1->stu_score_math;
    stu1->stu_score_math = stu2->stu_score_math;
    stu2->stu_score_math = score_tmp;
    score_tmp = stu1->stu_score_english;
    stu1->stu_score_english = stu2->stu_score_english;
    stu2->stu_score_english = score_tmp;
    score_tmp = stu1->stu_score_computer;
    stu1->stu_score_computer = stu2->stu_score_computer;
    stu2->stu_score_computer = score_tmp;
    stu1->stu_score_sum = stu1->stu_score_math + stu1->stu_score_english
            + stu1->stu_score_computer;
    stu1->stu_score_avg = stu1->stu_score_sum / 3;
    stu2->stu_score_sum = stu2->stu_score_math + stu2->stu_score_english
            + stu2->stu_score_computer;
    stu2->stu_score_avg = stu2->stu_score_sum / 3;
    return 0;
}


studentList.h//学生列表定义及其操作声明

/**
 * @file
 * 定义了学生列表结构体
 * 
 * @author 小代码
 */
#ifndef STUDENTLIST_H_
#define STUDENTLIST_H_
#include"student.h"
#include<stdio.h>
#include<stdbool.h>
/**
 * @brief 学生列表结构体定义
 * 
 */
struct _stu_list {
  
 /** @brief 链表头指针 */
 Stu head; 
  
 /** @brief 链表尾指针 */
 Stu last;
};
/** @brief 学生链表 */
typedef struct _stu_list sl;
/** @brief 指向学生链表的指针 */
typedef struct _stu_list * SL;
 
/**
 * @brief 创建一个初始化的链表
 * 
 * @return 指向 _stu_list 的指针
 * @retval NULL 创建失败
 */
SL list_init();
 
/**
 * @brief 从文件创建一个学生列表 
 * @param file_name 含有学生信息的文本文件的文件名
 * @return 返回学生列表
 * @retval NULL 创建失败
 */
SL list_create_file( char * file_name );
/**
 * @brief 销毁一个学生信息链表
 * 
 * @param stu_list 要销毁的链表的指针
 */
void list_destroy(SL stu_list);
 
/**
 * @brief 求学生信息链表的长度
 * 
 * @param stu_list 要求长度的学生信息链表
 * 
 * @return 学生信息链表 的长度
 * @retval -1 参数为空
 * 
 */
int list_len( SL stu_list );
/**
 * @brief 判断一个链表是否为空
 * 
 * @param stu_list 要判断是否为空的链表
 * 
 * @retval true 为空
 * @retval false 不为空
 * 
 */
bool list_is_empty( SL stu_list );
/**
 * @brief 在链表后追加一个元素
 * 
 * @param stu_list 要追加元素的链表
 * @param stu 要追加的元素
 * @return 返回的元素的指针
 * @retval NULL 追加失败
 */
Stu list_append(SL stu_list, Stu stu);
/**
 * @brief 根据学生的学号删除一个学生的信息
 * @param stu_list 保存学生信息的链表
 * @param stu_id 要删除的学生的学号
 * @return 返回被删除的学生
 * @retval NULL 删除失败
 */
Stu list_delete ( SL stu_list, int stu_id );
 
/**
 * @brief 输出一个链表的内容
 * 如果链表为空或参数为NULl,则没有任何输出
 * 
 * @param stu_list 要打印的链表
 */
void list_print( SL stu_list );
  
double list_score_sum(SL stu_list);
double list_score_avg(SL stu_list);
  
/**
 * @brief 根据学生号查的一个学生对象
 * 
 * @param stu_list 保存学生信息的链表
 * @param stu_id 要查的的学生的学号
 * @param stu 传出查询的学生
 * @return 查找结果
 * @retval -1 链表为空
 * @retval 1 查询成功
 * @retval 0 没有查到
 */
int list_search_id(SL stu_list, int stu_id, Stu stu);
 
/**
 * @brief 排序链表
 * 使用选择排序法
 * 
 * @param stu_list 要排序的学生链表
 */
void list_sort_avg(SL stu_list);
/**
 * @brief 把一个学生信息链表写入到当前目录中的一个TXT文本文件
 * 默认文件名为:student.txt\n
 * 根据排序的结果,从1开始对学生信息的 stu_score_grade 字段赋值
 * @param stu_list 要写入到文件的学生链表
 * @param file_name 械写入到的文件名
 * @return 写入到文件中的链表的指针
 */
FILE * list_save_txt(SL stu_list, char * file_name );
/**
 * @brief 列出平均分高于60的学生的信息
 * @param stu_list 学生信息链表
 * @return 分数高于60分的学生信息链表
 * @note 返回一个链表的功能还未实现
 */
SL list_pass(SL stu_list);
#endif /* STUDENTLIST_H_ */


studentList.c//学生列表操作实现

#include"studentList.h"
#include"student.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
/**
 * @brief 创建一个初始化的链表
 * 
 * @return 指向 _stu_list 的指针
 * @retval NULL 创建失败
 */
SL list_init() {
 SL stu_list = (SL) malloc(sizeof(sl));
 if ( NULL == stu_list) {
  printf("list_init..动态分配内存失败");
  exit(-1);
 }
 stu_list->head = stu_create(0, " ", 0.0, 0.0, 0.0);
 stu_list->last = stu_create(0, " ", 0.0, 0.0, 0.0);
 stu_list->head->prev = NULL;
 stu_list->head->next = stu_list->last;
 stu_list->last->prev = stu_list->head;
 stu_list->last->next = NULL;
 return stu_list;
}
/**
 * @brief 从文件创建一个学生列表 
 * @param file_name 含有学生信息的文本文件的文件名
 * @return 返回学生列表
 * @retval NULL 创建失败
 */
SL list_create_file( char * file_name ) {
 FILE * stu_file = fopen(file_name,"r");
 if ( NULL == stu_file) {
  return NULL;
 }
 SL stu_list = list_init();
 int stu_id = 0;
 char stu_name[10];
 double stu_math = 0.0;
 double stu_english = 0.0;
 double stu_computer = 0.0;
 while ( EOF
   != fscanf(stu_file, "%d\t%s\t%lf\t%lf\t%lf", &stu_id,
     stu_name, &stu_math, &stu_english,
     &stu_computer)) {
  Stu stu = stu_create(stu_id, stu_name, stu_math, stu_english,
    stu_computer);
//  stu_print( stu );
  list_append(stu_list, stu);
 }
 return stu_list;
}
 
/**
 * @brief 销毁一个学生信息链表
 * 
 * @param stu_list 要销毁的链表的指针
 */
void list_destroy(SL stu_list) {
 if ( NULL == stu_list) {
  return;
 }
 if (list_is_empty(stu_list)) {
  free(stu_list);
 }
 Stu tmp = stu_list->head->next;
 while (tmp != stu_list->last) {
  Stu f = tmp;
  tmp->prev->next = tmp->next;
  tmp->next->prev = tmp->prev;
  tmp = f->next;
  free(f);
 }
 free(stu_list);
}
  
/**
 * @brief 求学生信息链表的长度
 * 
 * @param stu_list 要求长度的学生信息链表
 * 
 * @return 学生信息链表 的长度
 * @retval -1 参数为空
 * 
 */
int list_len(SL stu_list) {
 if ( NULL == stu_list) {
  return -1;
 }
 int len = 0;
 if (list_is_empty(stu_list)) {
  len = 0;
 }
 Stu tmp = stu_list->head->next;
 while (tmp != stu_list->last) {
  len++;
  tmp = tmp->next;
 }
 return len;
}
 
/**
 * @brief 判断一个链表是否为空
 * 
 * @param stu_list 要判断是否为空的链表
 * 
 * @retval true 为空
 * @retval false 不为空
 */
bool list_is_empty(SL stu_list) {
 bool flags = false;
 if (stu_list->head->next == stu_list->last) {
  flags = true;
 }
 return flags;
}
 
/**
 * @brief 在链表后追加一个元素
 * 
 * @param stu_list 要追加元素的链表
 * @param stu 要追加的元素
 * @return 返回的元素的指针
 * @retval NULL 追加失败
 */
Stu list_append(SL stu_list, Stu stu) {
 if ( NULL == stu) {
  return NULL;
 }
 stu_list->last->prev->next = stu;
 stu->prev = stu_list->last->prev;
 stu->next = stu_list->last;
 stu_list->last->prev = stu;
 return stu;
}
/**
 * @brief 根据学生的学号删除一个学生的信息
 * @param stu_list 保存学生信息的链表
 * @param stu_id 要删除的学生的学号
 * @return 返回被删除的学生
 * @retval NULL 删除失败
 */
Stu list_delete(SL stu_list, int stu_id) {
 if ( NULL == stu_list) {
  return NULL;
 }
 int len = list_len(stu_list);
 if (len < 0) {
  return NULL;
 }
 Stu stu = NULL;
 list_search_id(stu_list,stu_id, stu );
 stu->next->prev = stu->prev;
 stu->prev->next = stu->next;
 free(stu);
 return NULL;
}
 
/**
 * @brief 输出一个链表的内容
 * 如果链表为空或参数为NULl,则没有任何输出
 * 
 * @param stu_list 要打印的链表
 */
void list_print(SL stu_list) {
 if (list_is_empty(stu_list)) {
  return;
 }
 print_title();
 Stu tmp = stu_list->head->next;
 while (tmp != stu_list->last) {
  stu_print(tmp);
  tmp = tmp->next;
 }
}
double list_score_sum(SL stu_list) {
 double sum = 0.0;
 Stu tmp = stu_list->head->next;
 while (tmp != stu_list->last) {
  sum += tmp->stu_score_math + tmp->stu_score_english
    + tmp->stu_score_computer;
  tmp = tmp->next;
 }
 return sum;
}
double list_score_avg(SL stu_list) {
 return list_score_sum(stu_list) / list_len(stu_list);
}
int list_search_id(SL stu_list, int stu_id , Stu stu) {
 if (list_is_empty(stu_list)) {
  return -1;
 }
 Stu tmp = stu_list->head->next;
// int i = 1;
// int len = list_len( stu_list );
 while (tmp != stu_list->last) {
  if( tmp->stu_id == stu_id ){
   break;
  }
  tmp = tmp->next;
 }
 if (tmp == stu_list->last) {
  tmp = NULL;
  return 0;
 }
 stu->stu_id = tmp->stu_id;
 strcpy( stu->stu_name, tmp->stu_name);
 stu->stu_score_math = tmp->stu_score_math;
 stu->stu_score_english = tmp->stu_score_english;
 stu->stu_score_computer = tmp->stu_score_computer;
  
 return 1;
}
void list_sort_avg(SL stu_list) {
 if (list_is_empty(stu_list) || 1 == list_len(stu_list)) {
  return;
 }
 Stu stu = stu_list->head->next;
 Stu stu_next = stu->next;
 Stu end = stu_list->last->prev;
 while (stu != end) {
//  stu_print( stu );
  stu_next = stu->next;
  while (stu_next != end->next) {
   if (stu->stu_score_avg < stu_next->stu_score_avg) {
    stu_swap(stu, stu_next);
   }
   stu_next = stu_next->next;
  }
  stu = stu->next;
  stu_next = stu_next->next;
 }
 stu = stu_list->head->next;
 int grade = 1;
 while (stu != stu_list->last) {
  stu->stu_score_grade = grade;
  grade++;
  stu = stu->next;
 }
}
FILE * list_save_txt(SL stu_list, char * file_name ) {
 if (list_is_empty(stu_list)) {
  return NULL;
 }
 FILE * fp = NULL;
 if ( NULL == (fp = fopen(file_name, "w"))) {
  printf("创建 !");
  exit(-1);
 }
 Stu stu = stu_list->head->next;
 while (stu != stu_list->last) {
  char stu_info[1024];
  sprintf(stu_info, "%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%d\n",
    stu->stu_id, stu->stu_name, stu->stu_score_math,
    stu->stu_score_english, stu->stu_score_computer,
    stu->stu_score_sum, stu->stu_score_avg,
    stu->stu_score_grade);
//  puts(stu_info);
  fputs(stu_info, fp);
  stu = stu->next;
 }
 if (0 != fclose(fp)) {
  puts("关闭文件失败!");
  exit(-1);
 }
 return NULL;
}
SL list_pass(SL stu_list) {
 if (list_is_empty(stu_list)) {
  return NULL;
 }
 Stu stu = stu_list->head->next;
 while (stu != stu_list->last) {
  if (stu->stu_score_avg >= 60) {
   stu_print(stu);
  }
  stu = stu->next;
 }
 return NULL;
}


stuxml.h//xml操作声明

/** @file stuxml.h
 * @brief 学生管理API
 */

#ifndef STUMAN_H_
#define STUMAN_H_
#include<libxml/tree.h>
#include"studentList.h"




/** @brief 创建一个学生信息的XML文件
 * 
 * @param xml_name 该文件的名字 ,默认为:student.man.xml
 * @return
 */
xmlDocPtr man_create_init(  char * xml_name );

/** @brief 根据一个学生列表创建一个保存学生信息的XML文件
 * 
 * @param stulist 学生列表
 * @param xml_name 文件名称
 * @return
 */
xmlDocPtr man_create_list(  SL stulist , char * xml_name );

/** @brief 根据学生创建一个子结点
 * 
 * @param stu 学生
 * @return 创建的子结点
 * @retval NULL 创建失败 
 */
xmlNodePtr man_create_node( Stu stu );


#endif /* STUMAN_H_ */


stuxml.c//xml操作实现

#include"stuxml.h"
#include"student.h"
#include"studentList.h"
#include<libxml/tree.h>
#include<libxml/parser.h>

/** @brief 创建一个学生信息的XML文件
 * 
 * @param xml_name 该文件的名字 ,默认为:student.man.xml
 * @return
 */
xmlDocPtr man_create_init(char * xml_name) {
    //文档指针
    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
    xmlNodePtr root = xmlNewNode( NULL, BAD_CAST "stulist");

    //设置XML文档的根属性
    xmlDocSetRootElement(doc, root);

    //保存文档
    int nRel = xmlSaveFile(xml_name, doc);
    if (nRel != -1) {
        printf("一个xml文档被创建,写入 %d 个字节\n", nRel);
    }
    

    return doc;
}

/** @brief 根据一个学生列表创建一个保存学生信息的XML文件
 * 
 * @param stulist 学生列表
 * @param xml_name 文件名称
 * @return
 */
xmlDocPtr man_create_list(SL stulist, char * xml_name) {
    if ( NULL == stulist) {
        puts("NULL == stulist");
        return NULL;
    }

    xmlDocPtr doc = man_create_init(xml_name);
    xmlNodePtr root = xmlDocGetRootElement(doc);

    if (list_is_empty(stulist)) {
        puts("列表为空");

        return doc;
    }

    Stu stu = stulist->head->next;
    while (stu != stulist->last) {

        xmlAddChild(root, man_create_node(stu));

        stu = stu->next;
    }

    //保存文档
    int nRel = xmlSaveFile(xml_name, doc);
//    if (nRel != -1) {
//        printf("一个xml文档被创建,写入 %d 个字节\n", nRel);
//    }
    
//    xmlSaveFileEnc( xml_name, doc, "UTF-8");
    nRel = xmlSaveFormatFileEnc( xml_name, doc, "UTF-8",1);
    printf("一个xml文档被创建,写入 %d 个字节\n", nRel);
    
    xmlFreeDoc( doc );

    return NULL;
}

/** @brief 根据学生创建一个子结点
 * 
 * @param stu 学生
 * @return 创建的子结点
 * @retval NULL 创建失败 
 */
xmlNodePtr man_create_node(Stu stu) {
    if ( NULL == stu) {
        return NULL;
    }
    char str[20];
    //创建一个子结点
    xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "student");
    //设置 id 属性
    sprintf(str, "%d", stu->stu_id);
    xmlNewProp(node, BAD_CAST "id", BAD_CAST str);

    //设置子结点
    xmlNewTextChild(node, NULL, BAD_CAST "stuName", BAD_CAST stu->stu_name);

    sprintf(str, "%.2lf", stu->stu_score_math);
    xmlNewTextChild(node, NULL, BAD_CAST "stuMath",
    BAD_CAST str);

    sprintf(str, "%.2lf", stu->stu_score_english);
    xmlNewTextChild(node, NULL, BAD_CAST "stuEnglish",
    BAD_CAST str);

    sprintf(str, "%.2lf", stu->stu_score_computer);
    xmlNewTextChild(node, NULL, BAD_CAST "stuComputer",
    BAD_CAST str);

    sprintf(str, "%d", stu->stu_score_grade);
    xmlNewTextChild(node, NULL, BAD_CAST "stuGrade",
    BAD_CAST str);

    return node;
}


输入的文件文件:以Tab键作为分隔符

1001    小代码    34    45    56
1002    老狼    25    16    56
1003    行者    34    13    77
1004    天涯    34    18    88
1005    散人    34    99    56

输出的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<stulist>
  <student id="1001">
    <stuName>小代码</stuName>
    <stuMath>34.00</stuMath>
    <stuEnglish>45.00</stuEnglish>
    <stuComputer>56.00</stuComputer>
    <stuGrade>-1</stuGrade>
  </student>
  <student id="1002">
    <stuName>老狼</stuName>
    <stuMath>25.00</stuMath>
    <stuEnglish>16.00</stuEnglish>
    <stuComputer>56.00</stuComputer>
    <stuGrade>-1</stuGrade>
  </student>
  <student id="1003">
    <stuName>行者</stuName>
    <stuMath>34.00</stuMath>
    <stuEnglish>13.00</stuEnglish>
    <stuComputer>77.00</stuComputer>
    <stuGrade>-1</stuGrade>
  </student>
  <student id="1004">
    <stuName>天涯</stuName>
    <stuMath>34.00</stuMath>
    <stuEnglish>18.00</stuEnglish>
    <stuComputer>88.00</stuComputer>
    <stuGrade>-1</stuGrade>
  </student>
  <student id="1005">
    <stuName>散人</stuName>
    <stuMath>34.00</stuMath>
    <stuEnglish>99.00</stuEnglish>
    <stuComputer>56.00</stuComputer>
    <stuGrade>-1</stuGrade>
  </student>
</stulist>


你可能感兴趣的:(libxml2)