Наиболее эффективная структура данных для хранения XML-дерева в C ++ - PullRequest
5 голосов
/ 17 апреля 2011

Я делаю некоторую работу с XML в C ++, и я хотел бы знать, какова лучшая структура данных для хранения данных XML. Пожалуйста, не говорите мне, что вы слышали в прошлом; Я хотел бы знать, какая структура наиболее эффективна. Я хотел бы иметь возможность хранить любое произвольное дерево XML (при условии, что оно допустимо) с минимальными затратами памяти и временем поиска.

Моей первоначальной мыслью был хеш, но я не мог понять, как обращаться с несколькими дочерними элементами одного и того же тега, а также как будут обрабатываться атрибуты.

Решения Qt приемлемы, но меня больше волнует общая структура, чем конкретная библиотека. Спасибо за ваш вклад.

Ответы [ 7 ]

5 голосов
/ 17 апреля 2011

Наиболее эффективной структурой будет набор классов, производных от DTD или схемы, которая определяет конкретные экземпляры XML, которые вы собираетесь обрабатывать. (Конечно, вы не собираетесь обрабатывать произвольный XML?) Теги представлены классами. Одинокие дети могут быть представлены полями. Дитя с минимальной или максимальной величиной может быть представлено полем, содержащим массив. Дочерние объекты с неопределенной арностью могут быть представлены динамически распределенным массивом. Атрибуты и дочерние элементы могут храниться в виде полей, часто с предполагаемым типом данных (если атрибут представляет число, зачем хранить его в виде строки?). Используя этот подход, вы часто можете перейти к определенному месту в документе XML, используя собственные пути доступа C ++, например, корне-> tag1.itemlist [1] -.> описание

Все они могут быть автоматически сгенерированы из схемы или DTD. Есть инструменты для этого. Альтова предлагает немного. У меня нет особого опыта в этом (хотя я создал подобные инструменты для Java и COBOL).

2 голосов
/ 17 апреля 2011

Сначала вы должны определить конкретные требования к эффективности с точки зрения хранения, скорости и т. Д. В конкретных числах. Не зная этой информации, вы не сможете определить, удовлетворяет ли ваша реализация требованию.

И, если у вас есть это требование, вы, вероятно, обнаружите, что DOM удовлетворяет ему и имеет преимущество в нулевом коде для поддержки.

Это будет кошмар для будущих программистов, поскольку они задаются вопросом, почему кто-то написал альтернативную реализацию DOM.

На самом деле, почти все, что вы делаете, будет просто реализацией DOM, но, возможно, неполным, с оптимизацией для индексации и т. Д. Я лично считаю, что повторное изобретение колеса должно быть последним, что вы считаете.

1 голос
/ 17 апреля 2011

Я думаю, что наиболее эффективное хранилище данных для хранения xml - это, вероятно, vtd-xml, который использует массив long вместо множества взаимосвязанных структур / классов. Основная идея заключается в том, что структуры / классы основаны на небольших распределителях памяти, которые в нормальных условиях влекут за собой серьезные накладные расходы. См. Эту статью для получения дополнительной информации.

http://soa.sys -con.com / узел / 250512

1 голос
/ 17 апреля 2011

уже существует библиотека C ++ XML: xerces.http://xerces.apache.org/xerces-c/install-3.html

есть некоторые древовидные структуры в \ include \ boost-1_46_1 \ boost \ intrusive \ есть красно-чёрное и avl-дерево, но я давно не смотрю на нихЯ не знаю, могут ли они быть особенно полезны.

XML - это древовидная структура.вы не знаете, какой будет структура, если только она не определена и не включена в DTD (хотя валидатор на валидроме разрывается на! DOCTYPE и не должен).

см. 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.

В сущности, вам нужно очень гибкое дерево, в котором корневой указатель указывает на список.каждый из этих узлов в списке содержит указатель, который может указывать на список.это должен быть упорядоченный список, поэтому сделайте это.Если ваша цель состоит в том, чтобы иметь возможность удалять данные, используйте вместо - они упорядочены, имея возможность легкой манипуляции.

слово предупреждения: .erase (итератор i) стирает все, начиная с и после i..erase (итератор i1, итератор 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, поэтому вы должны иметь возможность читать его для анализадокумент (или вы могли бы выбросить его).Вы также можете столкнуться с XML-схемой, преемником DTD.

0 голосов
/ 24 августа 2017

Я сам изучал эту проблему.И это мои мысли.

a) каждый элемент в xml является либо узлом, либо парой (ключ, значение).б) хранить каждый элемент в хэш.присвойте каждому элементу тип, т.е. "узел", "ключ, значение".в) у каждого элемента будет родитель.назначьте значение каждому из них.d) каждый элемент может иметь или не иметь дочерних элементов / ссылок.храните детей в дереве, которое будет определять ссылки.

Время поиска для любой клавиши будет O (1). Обратный путь может содержать список всех дочерних элементов внутри элемента.

Пожалуйста, просмотрите и предложите то, что я пропустил.

0 голосов
/ 17 апреля 2011

Я не уверен, какой самый эффективный метод, но поскольку DOM уже существует, зачем изобретать велосипед?

Может иметь смысл хэшировать все узлы по имени для поиска, но вы все равно должны использовать DOM в качестве основного представления.

0 голосов
/ 17 апреля 2011

Просто используйте DOM для хранения проанализированного XML-файла. Конечно, есть библиотека C ++ DOM. Вы можете запросить DOM с помощью выражений XPath.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...