我正在尝试解析以下XML文件:
<root>Root
<pai>Pai_1
<filho>Pai1,Filho1</filho>
<filho>Pai1,Filho2</filho>
</pai>
<pai>Pai_2
<filho>Pai2,Filho1</filho>
<filho>Pai2,Filho2</filho>
</pai>
</root>
我正在使用以下C代码:
//... open file
xml_tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
node = xml_tree;
printf("%s\n", mxmlGetText(node, NULL));
// here the return is: Root
// I expected: Root, OK
node = xml_tree->child;
printf("%s\n", mxmlGetText(node, NULL));
// here the return is: Root
// I expected: Pai_1, not OK
node = mxmlGetFirstChild(xml_tree);
printf("%s\n", mxmlGetText(node, NULL));
// here the return is: Root
// I expected: Pai_1, not OK
node = mxmlFindElement(xml_tree, xml_tree, "pai", NULL, NULL, MXML_DESCEND);
printf("%s\n", mxmlGetText(node, NULL));
// here the return is: Pai_1
// I expected: Pai_1, OK
node = mxmlGetNextSibling(node);
printf("%s\n", mxmlGetText(node, NULL));
// here the return is: (NULL)
// I expected: Pai_2, not OK
如何访问root的子级?我的访问概念在哪里错了?
谢谢。
@RutgersMike回复后编辑
我扩展你的while循环以尝试理解minixml的概念:
root = mxmlLoadFile(NULL,fp,MXML_TEXT_CALLBACK);
node = root;
printf("------- Root\n");
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
printf("\n");
printf("------- First child of Root\n");
node = mxmlGetFirstChild(node);
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
printf("\n");
printf("------- Sibling 1 of First child of Root\n");
node = mxmlGetNextSibling(node);
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
printf("\n");
printf("------- Sibling 2 of First child of Root\n");
node = mxmlGetNextSibling(node);
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
printf("\n");
printf("------- Sibling 3 of First child of Root\n");
node = mxmlGetNextSibling(node);
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
printf("\n");
printf("------- Sibling 4 of First child of Root\n");
node = mxmlGetNextSibling(node);
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
printf("\n");
结果是:
------- Root
Element = root
Value = Root
------- First child of Root
Element = (null)
Value = Root
------- Sibling 1 of First child of Root
Element = (null)
Value =
------- Sibling 2 of First child of Root
Element = pai
Value = Pai_1
------- Sibling 3 of First child of Root
Element = (null)
Value =
------- Sibling 4 of First child of Root
Element = pai
Value = Pai_2
我认为这个孩子和父母之间的导航概念有点奇怪。为什么兄弟之间有(空)值?
我正在考虑回到ezxml。
谢谢
答案 0 :(得分:7)
刚开始玩min-xml
,虽然我因为缺乏好的例子而感到非常沮丧,但我借用并增强了一个体面但不完美的例子来阅读XML文件并看到所有的部分。它显示标记之间的标记名称,属性和文本值。不确定如何识别结束标记。确保标准xml标记位于xml文件的顶部。包括stdio
,stdlib
,string
.h文件。
#include "mxml.h"
int main (int argc, char **argv ) {
FILE *fp = NULL;
int k = 0;
mxml_node_t * tree = NULL;
mxml_node_t * node = NULL;
if (argc < 2){
perror("Argument Required XML File ");
exit(1);
}
fp = fopen (argv[1], "r");
if (fp ){
tree = mxmlLoadFile (NULL , fp , MXML_OPAQUE_CALLBACK);
}else {
perror("Could Not Open the File Provided");
exit(1);
}
if (tree){
for (node = mxmlFindElement(tree, tree,NULL,NULL, NULL,MXML_DESCEND);
node != NULL;
node=mxmlWalkNext (node, NULL, MXML_DESCEND)
//node = mxmlFindElement(node, tree, NULL,NULL,NULL,MXML_DESCEND)
){
if (node->type == MXML_ELEMENT) {
printf("MXML_ELEMENT Node <%s>:%d \n", node->value.element.name, node->value.element.num_attrs);
for (k = 0; k < node->value.element.num_attrs; k++){
if (node->value.element.attrs ){
printf ("Attribute Name :: %s \n", node->value.element.attrs[k].name);
printf ("Attribute Value:: %s \n", node->value.element.attrs[k].value);
}
//if (!strncmp(node->value.element.name , "display-name", 12 )){
// printf(" String %s \n", (char*) node->child->value.text.string);
//}
}
}
else if (node->type == MXML_REAL){
printf("MXML_REAL Node is %s \n", node->value.element.name);
}
else if(node->type == MXML_OPAQUE){
printf("MXML_OPAQUE Node is %s \n", node->value.element.name);
}
else if(node->type == MXML_INTEGER){
printf("MXML_INTEGER Node is %s \n", node->value.element.name);
}
else if(node->type == MXML_TEXT){
printf("MXML_TEXT Node is %s \n", node->value.element.name);
}
else if(node->type == MXML_IGNORE){
printf("MXML_IGNORE Node is %s \n", node->value.element.name);
}
else if(node->type == MXML_CUSTOM){
printf("MXML_IGNORE Node is %s \n", node->value.element.name);
}
else {
printf("Type Default Node is %s \n", node->value.element.name);
}
}
}
if (tree){
mxmlDelete(tree);
}
if (fp){
fclose(fp);
}
return 0;
}
答案 1 :(得分:5)
看起来你想使用这里描述的迭代函数(http://www.minixml.org/mxml.html#3_7)来获取子节点。
编辑:我写这篇文章来迭代第一个子节点并且工作正常,使用mxmlGetFirstChild
和mxmlGetNextSibling
:
<!-- language: c -->
mxml_node_t* node = mxmlLoadFile(NULL,f,MXML_TEXT_CALLBACK);
while ( node != NULL )
{
switch ( mxmlGetType(node) )
{
case MXML_ELEMENT:
{
fprintf(stdout,"Element = %s\n",mxmlGetElement(node));
}
break;
case MXML_TEXT:
{
fprintf(stdout," Value = %s\n",mxmlGetText(node,0));
}
break;
default:
{
}
break;
}
mxml_node_t* next = mxmlGetFirstChild(node);
if ( next != NULL )
{
node = next;
}
else
{
next = mxmlGetNextSibling(node);
if ( next != NULL )
{
node = next;
}
else
{
node = next;
fprintf(stdout,"Done\n");
}
}
}
产生输出:
Element = root
Value = Root
Value =
Element = pai
Value = Pai_1
Value =
Element = filho
Value = Pai1,Filho1
我假设您可以使用其中一个getParent函数进行迭代备份,或者在使用一堆节点指针潜入一个子节点之前保存最后一个节点,如果您想迭代整个文件。请注意,我只处理/打印两种节点类型的数据 - 如果您还需要这些信息,您还需要尝试查看其他节点类型包含的内容。
**编辑后更多编辑**
前几天我建议其他人尝试libxml2
(http://xmlsoft.org/examples/index.html#xmlReader) - 检查该链接。 xmlReader示例显示用法。创建一个阅读器并迭代节点非常容易 - 当你点击每个节点时,只需检查它的类型以确定它是你关心的(通常是ELEMENT
,ATTRIBUTE
,TEXT
,和END_ELEMENT
),然后提取名称或值。我比mxml更喜欢它。