Как исправить проблемы с владением RapidXML String?

RapidXML - это быстрый и легкий C++ XML DOM Parser, но он имеет некоторые особенности.

Худшее из них, на мой взгляд, таково:

3.2 Право собственности на строки.

Узлам и атрибутам, созданным RapidXml, не принадлежат их строки имени и значения. Они просто держат указатели на них. Это означает, что вы должны быть осторожны при установке этих значений вручную, используя xml_base::name(const Ch *) или же xml_base::value(const Ch *) функции.

Необходимо позаботиться о том, чтобы время жизни передаваемой строки было, по крайней мере, таким же, как время жизни узла / атрибута. Самый простой способ добиться этого - выделить строку из memory_pool, принадлежащую документу. использование memory_pool::allocate_string() функция для этой цели.

Теперь я понимаю, что так сделано для скорости, но это похоже на автомобильную аварию, ожидающую своего появления. Следующий код выглядит безобидным, но "name" и "value" выходят из области видимости, когда возвращается foo, поэтому документ не определен.

void foo()
{
  char name[]="Name";
  char value[]="Value";

  doc.append_node(doc.allocate_node(node_element, name, value));
}

Предложение об использовании allocate_string() согласно ручным работам, но это так легко забыть.

Кто-нибудь "улучшил" RapidXML, чтобы избежать этой проблемы?

1 ответ

Решение

Я не использую RapidXML, но, возможно, мой подход может решить вашу проблему.

Я начал использовать Xerces, но я обнаружил, что он тяжел, помимо других мелких неприятностей, поэтому я перешел в CPPDOM. Когда я сделал этот шаг, я решил создать набор классов-оболочек, чтобы мой код не зависел от конкретного "движка" XML, и я мог при необходимости портировать на другой.

Я создал свои собственные классы для представления базовых объектов DOM (узел, документ и т. Д.). Эти классы внутренне используют идиому pimpl для использования объектов CPPDOM. Поскольку мой объект узла содержит "реальный" объект узла (из CPPDOM), я могу управлять чем угодно, поэтому правильное размещение и освобождение строк не будет проблемой там.

Поскольку мой код предназначен для CPPDOM, я не думаю, что он будет для вас очень полезным, но я могу опубликовать его, если хотите.

Кстати, если у вас уже есть слишком много кода, который уже использует RapidXML, вы можете воспроизвести его интерфейсы в ваших классах-оболочках. Я этого не делал, потому что код, который использовал Xerces, был не таким длинным, и мне все равно пришлось бы его переписать.

Другие вопросы по тегам