RapidXML является быстрый, легкий C++ Синтаксический анализатор XML DOM, но он имеет некоторые причуды.
Худший из них по моему мнению является этим:
3.2 Владение строк.
Узлы и атрибуты, произведенные RapidXml, не владеют своим именем и оценивают строки. Они просто содержат указатели на них. Это означает, что необходимо быть осторожными при устанавливании этих значений вручную, при помощи
xml_base::name(const Ch *)
илиxml_base::value(const Ch *)
функции.Необходимо соблюдать осторожность, чтобы гарантировать, что время жизни строки передало, по крайней мере целое время жизни узла/атрибута. Самый легкий способ достигнуть его состоит в том, чтобы выделить строку от memory_pool, принадлежавшего документу. Использовать
memory_pool::allocate_string()
функция с этой целью.
Теперь, я понимаю, что это сделало этот путь к скорости, но это чувствует себя подобно неизбежной автокатастрофе. Следующий код выглядит безвредным, но 'имя' и 'значение' вне объема, когда нечто возвращается, таким образом, документ не определен.
void foo()
{
char name[]="Name";
char value[]="Value";
doc.append_node(doc.allocate_node(node_element, name, value));
}
Предложение использования allocate_string()
согласно физическим трудам, но настолько легко забыть.
Кто-либо 'Улучшил' RapidXML для предотвращения этой проблемы?
Я не использую RapidXML, но, возможно, мой подход поможет решить вашу проблему.
Я начал использовать Xerces, но мне это показалось тяжелым, помимо других мелких неприятностей, поэтому я перешел на CPPDOM. Когда я сделал этот шаг, я решил создать набор классов-оболочек, чтобы мой код не зависел от конкретного «движка» XML, и я мог при необходимости переносить его на другой.
Я создал свои собственные классы для представления основных сущностей DOM (узел, документ и т. Д.). Эти классы внутренне используют идиому pimpl для использования объектов CPPDOM. Поскольку мой объект узла содержит «настоящий» объект узла (из CPPDOM), я могу управлять чем угодно по мере необходимости, поэтому правильное выделение и освобождение строк не будет проблема там.
Поскольку мой код предназначен для CPPDOM, я не думаю, что он был бы очень полезен для вас, но я могу опубликовать его, если хотите.
Кстати, если у вас уже есть слишком много кода, который уже использует RapidXML, вы можете воспроизвести его интерфейсы в своих классах-оболочках. Я не стал этого делать, потому что код, в котором использовался Xerces, был не таким длинным, и мне все равно пришлось бы его переписывать.