我正在用C ++中的XML做一些工作,我想知道存储XML数据的最佳数据结构是什么。请不要只告诉我你过去所听到的内容;我想知道最有效的结构是什么。我希望能够存储任意XML树(假设它是有效的),具有最小的内存开销和查找时间。
我最初的想法是哈希,但我无法弄清楚如何处理同一标签的多个孩子,以及如何处理属性。
Qt解决方案是可以接受的,但我更关心的是整体结构而不是特定的库。感谢您的投入。
答案 0 :(得分:5)
最有效的结构是从DTD或Schema派生的一组类,它们定义了您要处理的特定XML实例。 (当然你不会处理任意XML?)标签由类表示。单个孩子可以用字段表示。带有min ... max arity的Childen可以由包含数组的字段表示。具有不确定arity的子代可以由动态分配的数组表示。属性和子项可以存储为字段,通常使用推断的数据类型(如果属性表示数字,为什么将其存储为字符串?)。使用此方法,您通常可以使用本机C ++访问路径导航到XML文档中的特定位置,例如, 根 - > tag1.itemlist [1] - >描述
所有这些都可以从Schema或DTD自动生成。有工具可以做到这一点。 Altova提供一些。我对此没有具体经验(尽管我已经为Java和COBOL构建了类似的工具)。
答案 1 :(得分:2)
首先应根据具体数量确定存储,速度等方面的效率要求。在不知道这些信息的情况下,您无法判断您的实施是否满足要求。
并且,如果您有此要求,您可能会发现DOM满足它,并且具有零代码维护的优势。
对于未来的程序员来说,这将是一场噩梦,因为他们想知道为什么有人编写了DOM的替代实现。
实际上,你所做的任何事情都只是一个DOM实现,但可能是不完整的,并且对索引等进行了优化。我个人觉得重新发明轮子应该是你考虑的最后一件事。
答案 2 :(得分:1)
已经构建了一个C ++ XML库:xerces。 http://xerces.apache.org/xerces-c/install-3.html
\ include \ boost-1_46_1 \ boost \ intrusive \中有一些树结构 有一个红黑色和一个avl树,但长时间没看过那些,我不知道这些是否特别有用,我想不是。
XML是一种树结构。你不知道结构是什么,除非它有一个DTD定义并包含在一个(虽然验证器在validrome中断了!DOCTYPEs,它不应该)。
请参阅http://w3schools.com/xml/xml_tree.asp了解树例。
您可能会收到不遵循DTD或架构的内容。完全没有结构化。像这样:
<?xml version="1.0"?>
<a>
<b>hello
<e b="4"/>
<c a="mailto:jeff@nowhere.com">text</c>
</b>
<f>zip</f>
<z><b /><xy/></z>
<zook flag="true"/>
<f><z><e/></z>random</f>
</a>
我知道可查询的XML数据库确实存在,但我对它们知之甚少,除了它们可以处理非结构化数据。
PHP有一个XML解析器,它将它粘贴到PHP调用的数组中(不像C / C ++数组,因为数组可以有数组),你可以修改它以查看XML数据结构的示例应该有它。
你基本上想要的是一个非常灵活的树,其中根指针指向一个列表。列表中的每个节点都包含一个可以指向列表的指针。它应该是一个有序列表,所以把它做成一个。如果你的目的是能够删除数据,那么使用a而不是 - 它是有序的,同时具有易于操作的能力。
警告:.erase(iterator i)删除i之后的所有内容。 .erase(iterator i1,iterator i2)擦除了从i1到i2的所有内容。 .end()是一个迭代器,它在列表结尾后指向1,基本上什么都没有。 .begin()是一个指向列表开头的迭代器。
学习使用for_each(start,end,function){}或使用常规for语句。
迭代器就像指针一样。如此对待它们。
#include <iterator>
#include <list>
#include <iostream>
using namespace std;
list<class node> nodelist;
list<class node>::iterator nli;
for (nli=nodelist.begin(); nli!=nodelist.end(); nli++) {
cout<<nli->getData()<<endl;
}
节点需要有一个可选的属性列表,并注意到DTD可能包含在XML文档中,因此您必须能够读取它来解析文档(或者您可以将其丢弃)。您也可能遇到DTD的继承者XML Schema。
答案 3 :(得分:1)
我认为存储xml的最有效的数据结构可能是vtd-xml,它使用long数组而不是许多互连的结构/类。主要思想是结构/类基于小内存分配器,这在正常情况下会产生严重的开销。有关更多详细信息,请参阅此文章。
答案 4 :(得分:0)
只需使用DOM来存储已解析的XML文件。当然有C ++ DOM库。 您可以使用XPath表达式查询DOM。
答案 5 :(得分:0)
我不确定最有效的方法是什么,但由于DOM已经存在,为什么要重新发明轮子?
使用名称对所有节点进行查找可能是有意义的,但您仍应使用DOM作为基本表示。
答案 6 :(得分:0)
我自己一直在探索这个问题。而且,这些是我的想法。
a)xml中的每个元素都是节点或(键,值)对。 b)将每个元素存储在哈希中。为每个元素分配一个类型,即“节点”,“键,值”。 c)每个元素都有父母。为每个人分配一个值。 d)每个元素可能或可能没有子女/参考。将子项存储在btree中,该btree将定义引用。
任何键的搜索时间都是O(1)。参考遍历可以包含元素内所有子项的列表。
请查看并提出我错过的内容。