当前位置: 首页 > 工具软件 > Mini-XML > 使用案例 >

xml解析与生成工具mini-xml移植与使用

闻人栋
2023-12-01


mini-xml是c语音实现的xml生成与解析库,适合在纯c开发的嵌入式开发使用。

获取mini-xml源码

http://www.minixml.org/software.php下载libmxml库文件

编译mini-xml静态库

  1. 解压下载的源代码,配置编译工具

./configure --host=arm-hisiv300-linux

  1. 修改生产了Makefile文件
    将OBJS = mmd.o mxmldoc.o testmxml.o zipc.o $(LIBOBJS)
    修改为:OBJS = mmd.o $(LIBOBJS)

    在all: $(TARGETS) 行后增加如下内容:
    $(AR) -r libmxml.a $(OBJS)

  2. make编译,生成libmxml.a文件

使用mini-xml

  1. 编译使用mini-xml库自带的testmxml.c

gcc -o testmxml testmxml.c -lmxml -lpthread

  1. 编写自定义测试程序mymxml_test.c
#include <stdio.h>
#include <string.h>
#include "mxml.h"

typedef struct tagConfigBase
{
	char caVersion[8];
	char caSerialNo[16];
	char caDevName[256];
	int  iDevType;
} ConfigBase;

static ConfigBase	gstConfigBase;

void getConfigBase(ConfigBase *pstCfgBase)
{
	memcpy(pstCfgBase, &gstConfigBase, sizeof(ConfigBase));
}

void initDefaultCfgBase()
{
	memset(&gstConfigBase, 0, sizeof(ConfigBase));
	strncpy(gstConfigBase.caVersion, "1.0.8", sizeof(gstConfigBase.caVersion) - 1);
    strncpy(gstConfigBase.caSerialNo, "111111111", sizeof(gstConfigBase.caSerialNo) - 1);
    strncpy(gstConfigBase.caDevName, "mrj", sizeof(gstConfigBase.caDevName) - 1);
	gstConfigBase.iDevType = 1;
}

const char *				/* O - Whitespace string or NULL */
whitespace_cb(mxml_node_t *node,	/* I - Element node */
              int         where)	/* I - Open or close tag? */
{
  mxml_node_t	*parent;		/* Parent node */
  int		level;			/* Indentation level */
  const char	*name;			/* Name of element */
  static const char *tabs = "\t\t\t\t\t\t\t\t";
					/* Tabs for indentation */

  name = node->value.element.name;
	
  printf("name: %s, where = %d\n", name, where);
	
  if (!strcmp(name, "HHProtocol") || !strcmp(name, "ConfigBase"))
  {
      if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE) {
		  if (strcmp(name, "HHProtocol")) {
			return ("\n");
		  }
	  }
	  else if (!strcmp(name, "ConfigBase") && where == MXML_WS_AFTER_OPEN) {
		  return ("\n");
	  }
  }
  else if (!strcmp(name, "dl") || !strcmp(name, "ol") || !strcmp(name, "ul"))
  {
    return ("\n");
  }
  else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li"))
  {
    if (where == MXML_WS_BEFORE_OPEN)
      return ("\t");
    else if (where == MXML_WS_AFTER_CLOSE)
      return ("\n");
  }
  else if (!strncmp(name, "?xml", 4))
  {
    if (where == MXML_WS_AFTER_OPEN)
      return ("\n");
    else
      return (NULL);
  }
  else if (where == MXML_WS_BEFORE_OPEN ||
           ((!strcmp(name, "choice") || !strcmp(name, "option")) &&
	    where == MXML_WS_BEFORE_CLOSE))
  {
    for (level = -1, parent = node->parent;
         parent;
	 level ++, parent = parent->parent);

    if (level > 8)
      level = 8;
    else if (level < 0)
      level = 0;

    return (tabs + 8 - level);
  }
  else if (where == MXML_WS_AFTER_CLOSE ||
           ((!strcmp(name, "group") || !strcmp(name, "option") ||
	     !strcmp(name, "choice")) &&
            where == MXML_WS_AFTER_OPEN))
    return ("\n");
  else if (where == MXML_WS_AFTER_OPEN && !node->child)
    return ("\n");

  return (NULL);
}

int createConfigBase(char *pcPath)
{
	mxml_node_t *xml = NULL;
	mxml_node_t *protocol = NULL;
	mxml_node_t *configBase = NULL;
	mxml_node_t *node;
	
	xml = mxmlNewXML("1.0");
	if (!xml) {
		printf("mxmlNewXML fail!\n");
		return -1;
	}
	
	protocol = mxmlNewElement(xml, "HHProtocol");
	configBase = mxmlNewElement(protocol, "ConfigBase");
	node = mxmlNewElement(configBase, "DevSN");
	mxmlNewText(node, 0, gstConfigBase.caSerialNo);
	node = mxmlNewElement(configBase, "FmVersion");
	mxmlNewText(node, 0, gstConfigBase.caVersion);
	node = mxmlNewElement(configBase, "DevName");
	mxmlNewText(node, 0, gstConfigBase.caDevName);
	node = mxmlNewElement(configBase, "DevTypeID");
	mxmlNewInteger(node, gstConfigBase.iDevType);
	
	FILE *fp;
	fp = fopen(pcPath, "w");
	mxmlSaveFile(xml, fp, whitespace_cb);
	fclose(fp);
	mxmlDelete(xml);
	
	printf("create configBase.xml success!\n");
	
	return 0;
}


int loadConfigBase(const char *pcFile, ConfigBase *pstCfgBase)
{   
    FILE *fp;
    mxml_node_t *tree, *node, *element;
    fp = fopen(pcFile, "r");
    if (fp == NULL) {
        printf("open xml file %s fail!\n", pcFile);
        return -1;
    }

    tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
    fclose(fp);

    node = mxmlFindElement(tree, tree, "ConfigBase",
                           NULL, NULL,
                           MXML_DESCEND);
                           
    element = mxmlFindElement(node, tree, "DevSN",
                           NULL, NULL,
                           MXML_DESCEND);
    
    printf("%s\n", element->child->value.text.string);
    
    element = mxmlFindElement(node, tree, "FmVersion",
                           NULL, NULL,
                           MXML_DESCEND);

    printf("%s\n", element->child->value.text.string);

    element = mxmlFindElement(node, tree, "DevName",
                           NULL, NULL,
                           MXML_DESCEND);

    printf("%s\n", element->child->value.text.string);
    
    element = mxmlFindElement(node, tree, "DevTypeID",
                           NULL, NULL,
                           MXML_DESCEND);

    printf("%s\n", element->child->value.text.string);

    mxmlDelete(tree);
    
    return 0;
}

int main()
{
	initDefaultCfgBase();
	createConfigBase("base.xml");
	ConfigBase confBase;
	loadConfigBase("base.xml", &confBase);
	return 0;
}

Makefile

TARGET = mxml_test

CC = arm-hisiv300-linux-gcc
LD = arm-hisiv300-linux-ld
AR = arm-hisiv300-linux-ar

CSRCS = $(wildcard *.c)
OBJS = $(CSRCS:.c = .o)

INCLUDE = -I/xxx
LIBS = libmxml.a
CPPFLAGS = -g -Wall -lpthread

ifdef DEBUG_MEMORY
		CPPFLAGS += -DDEBUG_MEMORY 
endif

$(TARGET) : $(OBJS)
		$(CC) $^ -o $@ $(CPPFLAGS) $(LIBS)

%.o: %.c 
		$(CC) -c $(CPPFLAGS) -o $@ $< 
clean:
		rm *.o $(TARGET)

.PHONY:clean

 类似资料: