我正在尝试解析以下 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
如何访问根的 child ?我的访问概念在哪里错误?
谢谢你。
在@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
我认为这种在 child 和 parent 之间导航的概念有点奇怪。为什么 sibling 之间有(空)值?
我正在考虑回到ezxml。
谢谢
最佳答案
看起来您想使用此处描述的迭代函数 ( 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
),然后取出名称或值(value)。我比 mxml 更喜欢它。关于c - miniXML 解析 C API,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9806996/