2014-09-23 2 views
0

Я пытаюсь что-то вроде этого,как заполнить XML-документ с помощью rapidxml C++

#include "stdafx.h" 
#include "rapidxml.hpp" 
//#include "rapidxml_iterators.hpp" 
#include "rapidxml_print.hpp" 
#include "rapidxml_utils.hpp" 
#include <iostream> 
#include <stdio.h> 

using namespace rapidxml; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 

    std::ofstream theFile ("trial.xml"); 
    xml_document<> doc; 
    xml_node<>* decl = doc.allocate_node(node_declaration); 
    decl->append_attribute(doc.allocate_attribute("version", "1.0")); 
    decl->append_attribute(doc.allocate_attribute("encoding", "UTF-8")); 
    doc.append_node(decl); 
    xml_node<>* root = doc.allocate_node(node_element, "page"); 
    root->append_attribute(doc.allocate_attribute("xmlns", "http://ALTEC-Center.org/xsd/ocr-annotation-1-0.xsd")); 
    root->append_attribute(doc.allocate_attribute("Number of lines", "10")); 
    doc.append_node(root); 
    for (int i = 0; i < 8; i++) 
    { 
     //char buf1[8]; 
     //std::sprintf(buf1, "%d", i); 
     xml_node<>* child = doc.allocate_node(node_element, "line"); 
     child->append_attribute(doc.allocate_attribute("Index",std::to_string(i).c_str())); 
     root->append_node(child); 

     for (int j = 0; j < 8; j++) 
     { 
      xml_node<>* child1 = doc.allocate_node(node_element, "word"); 
      child1->append_attribute(doc.allocate_attribute("Index",std::to_string(j).c_str())); 
      child1->append_attribute(doc.allocate_attribute("x","0.0")); 
      child1->append_attribute(doc.allocate_attribute("y","0.1")); 
      child1->append_attribute(doc.allocate_attribute("width","0.2")); 
      child1->append_attribute(doc.allocate_attribute("hight","0.3")); 
      child1->append_attribute(doc.allocate_attribute("word","محمد")); 
      child->append_node(child1); 
     } 
    } 
    theFile << doc; 
    theFile.close(); 
    doc.clear(); 

    return 0; 
} 

но выход следующим образом,

<line Index=" "> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
    <word Index=" " x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
</line> 

и я хочу «индекс» атрибут = итератор значение цикла «i» и «j», как

<word Index="0" x="0.0" y="0.1" width="0.2" hight ="0.3" word="محمد"/> //j=0 
<word Index="1" x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> //j=1 
<word Index="2" x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 
<word Index="3" x="0.0" y="0.1" width="0.2" hight="0.3" word="محمد"/> 

и так далее. В предыдущем примере я просто попытался использовать параметр цикла как есть, но позже я хочу заполнить атрибуты чем-то вроде word[i][j], как я мог это сделать?

ответ

0

Вы сталкиваетесь с одной из наиболее распространенных проблем быстрого xml: при создании XML-документа таким образом, RapidXML не создает копии строковых данных, которые вы предоставляете, он просто хранит указатели на них. (Это большая часть того, что делает его Rapid).

Так что, когда вы используете этот

child->append_attribute(doc.allocate_attribute("Index",std::to_string(i).c_str())); 

.. это хранение указателя на временные строки, возвращаемых из to_string(i). Эта память будет перезаписана, поэтому ваш XML-документ будет изменяться.

Вместо этого следует выделить строку временного rapidXml для сохранения текста:

char * idxStr = doc.allocate_string(std::to_string(i).c_str()); 
child->append_attribute(doc.allocate_attribute("Index", idxStr)); 

Вы всегда должны это делать, если вы не используете символьную строку (например, "0.3")