现在的位置: 首页 > 综合 > 正文

XML DOM解析

2013年10月02日 ⁄ 综合 ⁄ 共 5486字 ⁄ 字号 评论关闭

1 DOM原理:

由于XML文件可以视为一个树型数据结构,DOM就是把这文档读到一棵树中,放到内存里,然后通过DOM提供的函数进行解析的一种XML解析方法。
 
2 DOM结点类型:
DOM结点有以下几种类型,可以通过XmlDomGetNodeType()方法获得返回值(int)。
ELEMENT_NODE=1
ATTRIBUTE_NODE=2
TEXT_NODE=3
CDATA_SECTION_NODE=4
ENTITY_REFERENCE_NODE=5
ENTITY_NODE=6
PROCESSING_INSTRUCTION_NODE=7
COMMENT_NODE=8
DOCUMENT_NODE=9
DOCUMENT_TYPE_NODE=10
DOCUMENT_FRAGMENT_NODE=11
NOTATION_NODE=12
 
其中13为我们这里的常用类型。
 
3 DOM解析的步骤:
XmlCreate():建立一个XML CONTEXT,这是Oracle的特有步骤。
/* Create a XML Context */
         xctx = XmlCreate(&ecode, (oratext *)"XDEBUG", NULL);
         if (xctx == NULL)
         {
                   perror("XmlCreate");
                   return -1;
         }
 
XmlLoadDom():读取XML文件在内存中建立DOM树型结构。
/* Load DOM */
         doc = XmlLoadDom(xctx, &ecode, "file", "test.xml", "discard_whitespace", TRUE, NULL);
         if (doc == NULL)
         {
                   perror("XmlLoadDom");
                   return -1;
         }
 
XmlDomGetDocElem():获得XML文件的根结点,这个结点一般都由发送和接收端末协商确定好,为了端末解析方便。例如:<TableName>
/* Get root node */
root = XmlDomGetDocElem(xctx, doc);
         if (root == NULL)
         {
                   printf("No root node./n");
                   return -1;
         }
 
接下来就是对具体XML文件中结点的解析过程了,这个过程通常用循环完成,例如:
for (i = XmlDomGetFirstChild(xctx, root); i != NULL; i = XmlDomGetNextSibling(xctx, i))
         {
                   for (j = XmlDomGetFirstChild(xctx, i); j != NULL; j = XmlDomGetNextSibling(xctx, j))
                   {
                            text = XmlDomGetNodeName(xctx, j);
                            strcpy(name, text);
                            k = XmlDomGetFirstChild(xctx, j);
                            text = XmlDomGetNodeValue(xctx, k);
                            strcpy(value, text);
                            printf("%s: %s/n", name, value);
                   }
                   printf("/n");
         }
 
4 DOM解析中的常用函数:
Ø        XmlDomGetFirstChild():取得某结点的第一个孩子结点。
Ø        XmlDomGetNextSibling():取得某结点的下一个孩子结点,直到返回NULL
Ø        XmlDomGetNodeName():取得某结点的名字。
Ø        XmlDomGetNodeValue():取得某结点的值,只有Attr, CDATA, Comment, ProcessingInstructionText nodes可以取值。
 
5 DOM文件解析举例:
5.1 XML文件:
<TableName>
         <row>
                   <ID>12345678</ID>
                   <WIN1>12345</WIN1>
                   <WIN2>00000</WIN2>
                   <PPT>1</PPT>
         </row>
         <row>
                   <ID>88888888</ID>
                   <WIN1>11111</WIN1>
                   <WIN2>22222</WIN2>
                   <PPT>2</PPT>
         </row>
</TableName>
 
5.2 DOM解析代码:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <xml.h>
 
int main()
{
         xmlctx *xctx;       /* Xml Context */
         xmlerr ecode;      /* Error code */
         xmldocnode *doc;    /* Xml document node */
         xmlnode *i, *j, *k; /* Temp node pointer */
         xmlelemnode *root; /* Root node */
         oratext *text;      /* Temp string pointer */
 
         /* Buffer */
         char name[256];
         char value[256];
 
         /* Create a XML Context */
         xctx = XmlCreate(&ecode, (oratext *)"XDEBUG", NULL);
         if (xctx == NULL)
         {
                   perror("XmlCreate");
                   return -1;
         }
 
         /* Load DOM */
         doc = XmlLoadDom(xctx, &ecode, "file", "test.xml", "discard_whitespace", TRUE, NULL);
         if (doc == NULL)
         {
                   perror("XmlLoadDom");
                   return -1;
         }
 
         /* Get root node */
         root = XmlDomGetDocElem(xctx, doc);
         if (root == NULL)
         {
                   printf("No root node./n");
                   return -1;
         }
 
         /* Get row node */
         for (i = XmlDomGetFirstChild(xctx, root); i != NULL; i = XmlDomGetNextSibling(xctx, i))
         {
                   /* Get database column */
                   for (j = XmlDomGetFirstChild(xctx, i); j != NULL; j = XmlDomGetNextSibling(xctx, j))
                   {
                            /* Get column name */
                            text = XmlDomGetNodeName(xctx, j);
                            strcpy(name, text);
                           
                            /* Get value */
                            k = XmlDomGetFirstChild(xctx, j);
                            text = XmlDomGetNodeValue(xctx, k);
                            strcpy(value, text);
 
                            /* Print to stdout */
                            printf("%s: %s/n", name, value);
                   }
                   printf("/n");
         }
 
         return 0;
}
 
5.3 Makefile:
#################################################################
#                     PRIVATE PART                              #
#################################################################
# define global variables
EXE=$(HOME)/src/dai_weitao/xml_parse/test
 
OBJS=main.o
 
# include head file path
INC_DIR= -I$(HOME)/include
 
# include head file path( for proc )
PROC_INC= $(HOME)/include
 
# the library path
PROC_LIBS= $(LDPATHFLAG)$(LIBHOME) $(STATICPROLDLIBS) $(STATICPROLDLIBS)
LIBLIST=-lclntsh -lxml10
#MFLAGS= -g -DDEBUG -xarch=v9
MFLAGS= -g -DDEBUG -xarch=v9
MFLAGS= -g -DDEBUG -xarch=v9 -xarch=generic64
 
# define the target item
all: $(OBJS)
         $(CC) $(MFLAGS) $(LFLAGS) -o $(EXE) $(INC_DIR) $(OBJS) -L$(ORACLE_HOME)/lib $(LIBLIST)
 
clean:
         rm -f $(OBJS)
         rm -f $(EXE)
 
#################################################################
#                        COMMON PART                            #
#################################################################
# include the precompiler part makefile
include $(ORACLE_HOME)/precomp/lib/env_precomp.mk
PROC_OPTION= PARSE=NONE LINES=YES CLOSE_ON_COMMIT=YES RELEASE_CURSOR=YES LTYPE=NONE CODE=ANSI_C
 
# suffixes rules
.SUFFIXES: .pc .c .o
 
.pc.c:
         $(PROC) $(PROCFLAGS) $(PROC_OPTION) INCLUDE=$(PROC_INC) iname=$*
 
.pc.o:
         $(PROC) $(PROCFLAGS) $(PROC_OPTION) INCLUDE=$(PROC_INC) iname=$*
         $(CC) $(MFLAGS) $(CFLAGS) $(INC_DIR) -c $*.c
 
.c.o:
         $(CC) $(MFLAGS) $(CFLAGS) $(INC_DIR) -c $*.c

抱歉!评论已关闭.