RapidXML, чтение и сохранение значений - PullRequest
3 голосов
/ 06 февраля 2010

Я работал с источниками rapidXML и смог прочитать некоторые значения. Теперь я хочу изменить их и сохранить в своем XML-файле:

Разбор файла и установка указателя

void SettingsHandler::getConfigFile() {
    pcSourceConfig = parsing->readFileInChar(CONF);

    cfg.parse<0>(pcSourceConfig);
}

Чтение значений из XML

void SettingsHandler::getDefinitions() {    
    SettingsHandler::getConfigFile();
    stGeneral = cfg.first_node("settings")->value();
    /* stGeneral = 60 */
}

Изменение значений и сохранение в файл

void SettingsHandler::setDefinitions() {
    SettingsHandler::getConfigFile();

    stGeneral = "10";

    cfg.first_node("settings")->value(stGeneral.c_str());

    std::stringstream sStream;
    sStream << *cfg.first_node();

    std::ofstream ofFileToWrite;
    ofFileToWrite.open(CONF, std::ios::trunc);
    ofFileToWrite << "<?xml version=\"1.0\"?>\n" << sStream.str() << '\0';
    ofFileToWrite.close();
}

Чтение файла в буфер

char* Parser::readFileInChar(const char* p_pccFile) {
    char* cpBuffer;
    size_t sSize;

    std::ifstream ifFileToRead;
    ifFileToRead.open(p_pccFile, std::ios::binary);
    sSize = Parser::getFileLength(&ifFileToRead);
    cpBuffer = new char[sSize];
    ifFileToRead.read( cpBuffer, sSize);
    ifFileToRead.close();

    return cpBuffer;
}

Однако сохранить новое значение невозможно. Мой код просто сохраняет исходный файл со значением «60», где оно должно быть «10».

Rgds Лэйн

Ответы [ 3 ]

2 голосов
/ 12 марта 2010

Я думаю, что это RapidXML Gotcha

Попробуйте добавить флаг parse_no_data_nodes к cfg.parse<0>(pcSourceConfig)

1 голос
/ 14 августа 2011

Используйте следующий метод для добавления атрибута в узел. Метод использует выделение памяти для строк из rapidxml. Таким образом, rapidxml заботится о строках, пока документ жив. См. http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_1modifying_dom_tree для получения дополнительной информации.

void setStringAttribute(
        xml_document<>& doc, xml_node<>* node,
        const string& attributeName, const string& attributeValue)
{
    // allocate memory assigned to document for attribute value
    char* rapidAttributeValue = doc.allocate_string(attributeValue.c_str());
    // search for the attribute at the given node
    xml_attribute<>* attr = node->first_attribute(attributeName.c_str());
    if (attr != 0) { // attribute already exists
        // only change value of existing attribute
        attr->value(rapidAttributeValue);
    } else { // attribute does not exist
        // allocate memory assigned to document for attribute name
        char* rapidAttributeName = doc.allocate_string(attributeName.c_str());
        // create new a new attribute with the given name and value
        attr = doc.allocate_attribute(rapidAttributeName, rapidAttributeValue);
        // append attribute to node
        node->append_attribute(attr);
    }
}
1 голос
/ 06 февраля 2010

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

if ( ! ofFileToWrite << "<?xml version=\"1.0\"?>\n" 
       << sStream.str() << '\0' ) {
    throw "write failed";
}

Обратите внимание, что вам не нужен терминатор '\ 0', но это не должно причинить никакого вреда.

...