使用 xml 解析器 expat 获取 xml 数据
我已经成功解析了。 但现在我无法获取这些值 我需要的。 我可以获得元素和属性。 但无法获取值。 我想得到这个xml中frame的值,它是20。
/* track the current level in the xml tree */
static int depth = 0;
/* first when start element is encountered */
void start_element(void *data, const char *element, const char **attribute)
{
int i;
for(i = 0; i < depth; i++)
{
printf(" ");
}
printf("%s", element);
for(i = 0; attribute[i]; i += 2)
{
printf(" %s= '%s'", attribute[i], attribute[i + 1]);
}
printf("\n");
depth++;
}
/* decrement the current level of the tree */
void end_element(void *data, const char *el)
{
depth--;
}
int parse_xml(char *buff, size_t buff_size)
{
FILE *fp;
fp = fopen("start_indication.xml", "r");
if(fp == NULL)
{
printf("Failed to open file\n");
return 1;
}
XML_Parser parser = XML_ParserCreate(NULL);
int done;
XML_SetElementHandler(parser, start_element, end_element);
memset(buff, 0, buff_size);
printf("strlen(buff) before parsing: %d\n", strlen(buff));
size_t file_size = 0;
file_size = fread(buff, sizeof(char), buff_size, fp);
/* parse the xml */
if(XML_Parse(parser, buff, strlen(buff), XML_TRUE) == XML_STATUS_ERROR)
{
printf("Error: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
}
fclose(fp);
XML_ParserFree(parser);
return 0;
}
<data>
<header length="4">
<item name="time" type="time">16</item>
<item name="ref" type="string">3843747</item>
<item name="port" type="int16">0</item>
<item name="frame" type="int16">20</item>
</header>
</data>
Output from parsing
Element: data
Element: header length= '4'
Element: item name= 'time' type= 'time'
Element: item name= 'ref' type= 'string'
Element: item name= 'port' type= 'int16'
Element: item name= 'frame' type= 'int16'
I have managed to parse ok. But now I am having trouble getting the values
that I need. I can get the element and the attributes. But cannot get the values.
I would like to get the value of frame in this xml it is 20.
/* track the current level in the xml tree */
static int depth = 0;
/* first when start element is encountered */
void start_element(void *data, const char *element, const char **attribute)
{
int i;
for(i = 0; i < depth; i++)
{
printf(" ");
}
printf("%s", element);
for(i = 0; attribute[i]; i += 2)
{
printf(" %s= '%s'", attribute[i], attribute[i + 1]);
}
printf("\n");
depth++;
}
/* decrement the current level of the tree */
void end_element(void *data, const char *el)
{
depth--;
}
int parse_xml(char *buff, size_t buff_size)
{
FILE *fp;
fp = fopen("start_indication.xml", "r");
if(fp == NULL)
{
printf("Failed to open file\n");
return 1;
}
XML_Parser parser = XML_ParserCreate(NULL);
int done;
XML_SetElementHandler(parser, start_element, end_element);
memset(buff, 0, buff_size);
printf("strlen(buff) before parsing: %d\n", strlen(buff));
size_t file_size = 0;
file_size = fread(buff, sizeof(char), buff_size, fp);
/* parse the xml */
if(XML_Parse(parser, buff, strlen(buff), XML_TRUE) == XML_STATUS_ERROR)
{
printf("Error: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
}
fclose(fp);
XML_ParserFree(parser);
return 0;
}
<data>
<header length="4">
<item name="time" type="time">16</item>
<item name="ref" type="string">3843747</item>
<item name="port" type="int16">0</item>
<item name="frame" type="int16">20</item>
</header>
</data>
Output from parsing
Element: data
Element: header length= '4'
Element: item name= 'time' type= 'time'
Element: item name= 'ref' type= 'string'
Element: item name= 'port' type= 'int16'
Element: item name= 'frame' type= 'int16'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于外国人来说这是相当困难的。 当您只对结构感兴趣而不是元素的内容时,expat 会更好。 为什么不使用 libxml 来代替? 您使用基于偶数的解析器(例如 expat)而不是基于树的解析器的原因是什么?
不管怎样,方法是设置一个字符数据处理程序。 这是一个基于您的代码的示例:
It is quite difficult with expat. expat is better when you are only interested with the structure, not the content of the elements. Why not using libxml instead? What are your reasons for using an even-based parser like expat, rather than a tree-based one?
Anyway, the way to do it is to set a character data handler. Here is an example, based on your code:
“值”20是标签名为“item”、名称属性为“frame”的元素中的字符数据“20”。
要接收字符数据事件,请使用
XML_SetCharacterDataHandler
函数。该回调将接收字符数据。 解析器可能会分割字符数据 - 通常是为了处理到达缓冲区末尾的情况,或者对于实体(因此对于
foo&bar
,您的处理程序将收到三个调用 - “foo”、“&”和“bar”),因此如果您需要整个数据,则必须再次将字符串部分粘贴在一起。当您收到下一个元素开始或关闭回调时,您就知道节点内的所有字符数据何时都已存在。
当你拥有了所有的角色数据后,就可以对其进行处理了。
从您的代码简化的独立示例:
The 'value' 20 is the character data "20" in the element whose tagname is "item" and whose name attribute is "frame".
To receive character data events, register a callback with the
XML_SetCharacterDataHandler
function.This callback will receive the character data. The parser may split character data - typically to handle reaching the end of a buffer, or for entities (so for
foo&bar
your handler will get three calls - "foo", "&" and "bar"), so you have to paste the string parts together again if you need the whole of the data.You know when you have all the character data inside a node when you receive the next element start or close callback.
When you have all the character data, you can process it.
A stand-alone example simplified from your code: