2013-04-21 2 views
6

Я использую дерево свойств Boost для чтения и записи XML. Используя приложение для работы с электронными таблицами, я сделал, чтобы сохранить содержимое таблицы в xml. Это назначение школы, так что я должен использовать следующий формат для XML:Добавление узлов с тем же ключом в дерево свойств

<?xml version="1.0" encoding="UTF-8"?> 
<spreadsheet> 
    <cell> 
     <name>A2</name> 
     <contents>adsf</contents> 
    </cell> 
    <cell> 
     <name>D6</name> 
     <contents>345</contents> 
    </cell> 
    <cell> 
     <name>D2</name> 
     <contents>=d6</contents> 
    </cell> 
</spreadsheet> 

Для простой тестовой программы я писал:

int main(int argc, char const *argv[]) 
{ 
boost::property_tree::ptree pt; 

pt.put("spreadsheet.cell.name", "a2"); 
pt.put("spreadsheet.cell.contents", "adsf"); 

write_xml("output.xml", pt); 

boost::property_tree::ptree ptr; 
read_xml("output.xml", ptr); 

ptr.put("spreadsheet.cell.name", "d6"); 
ptr.put("spreadsheet.cell.contents", "345"); 
ptr.put("spreadsheet.cell.name", "d2"); 
ptr.put("spreadsheet.cell.contents", "=d6"); 

write_xml("output2.xml", ptr); 

return 0; 
} 

Основываясь на этом question я вижу метод put заменяющего ничего на этом узле, вместо добавления нового. Какие именно функциональность я вижу:

Output.xml

<?xml version="1.0" encoding="utf-8"?> 
<spreadsheet> 
    <cell> 
    <name>a2</name> 
    <contents>adsf</contents> 
    </cell> 
</spreadsheet> 

Output2.xml

<?xml version="1.0" encoding="utf-8"?> 
<spreadsheet> 
    <cell> 
    <name>d2</name> 
    <contents>=d6</contents> 
    </cell> 
</spreadsheet> 

Глядя на documentation я вижу этот add_child метод, который будет Add the node at the given path. Create any missing parents. If there already is a node at the path, add another one with the same key.

Я не могу понять, как использовать этот метод add_child, может кто-нибудь объяснить, как его использовать?

Есть ли лучший способ сделать это для достижения формата файла, который я хочу?

+0

Разве вы не можете просто использовать имя ячейки во имя ребенка? то есть '' spreadsheet.cell.d6 "' –

+0

@ k-ballo, потому что это не соответствует требованиям xml. – Deekor

ответ

15

Функция члена add_child позволяет вставить один property_tree в DOM другого в качестве дочернего узла. Если указанный вами путь ключа уже существует, будет добавлен дублирующий ключ и вместо него будет вставлен дочерний элемент. Если мы немного изменим ваш пример, мы сможем рассмотреть результаты.

#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 

int main() 
{ 
    // Create the first tree with two elements, name and contents 
    boost::property_tree::ptree ptr1; 
    ptr1.put("name", "a2"); 
    ptr1.put("contents", "adsf"); 

    // Create the a second tree with two elements, name and contents 
    boost::property_tree::ptree ptr2; 
    ptr2.put("name", "d6"); 
    ptr2.put("contents", "345"); 

    // Add both trees to a third and place them in node "spreadsheet.cell" 
    boost::property_tree::ptree ptr3; 
    ptr3.add_child("spreadsheet.cell", ptr1); 
    ptr3.add_child("spreadsheet.cell", ptr2); 

    boost::property_tree::write_xml("output.xml", ptr3); 

    return 0; 
} 

При вызове add_child в первый раз, узел для ключа «spreadsheet.cell» не существует, и создается. Затем он добавляет содержимое дерева (name и contents) к вновь созданному узлу. Когда вы вызываете add_child во второй раз, он видит, что «spreadsheet.cell» уже существует, но в отличие от put он создает узел, который также называется «ячейкой» и вставляет его в том же месте.

Конечный результат:

<?xml version="1.0" encoding="utf-8"?> 
<spreadsheet> 
    <cell> 
    <name>a2</name> 
    <contents>adsf</contents> 
    </cell> 
    <cell> 
    <name>d6</name> 
    <contents>345</contents> 
    </cell> 
</spreadsheet> 
+0

Удивительное объяснение. Если бы мне захотелось обновить cell 'd6', как бы я мог перейти к этой ячейке и изменить содержимое в' ptr3'? – Deekor

+2

@Deekor Итерации над детьми 'spreadsheet' ищет всех детей типа' cell'. Каждый раз, когда вы сталкиваетесь, вы получаете содержимое «name», и если вы найдете совпадение, удалите его. Вам нужно будет ознакомиться с документами по спецификациям –

+0

приятное объяснение, а не документация вокруг add_child в сети иначе. – sb32134

Смежные вопросы