Frage

In meinem C++-Programm möchte ich ein kleines Stück XML analysieren, einige Knoten einfügen und dann das neue XML extrahieren (vorzugsweise als std::string).
RapidXml wurde mir empfohlen, aber ich sehe nicht, wie ich das XML als Textzeichenfolge zurückholen kann.
(Ich könnte über die Knoten und Attribute iterieren und es selbst erstellen, aber es gibt sicherlich eine eingebaute Funktion, die mir fehlt.)
Danke schön.

War es hilfreich?

Lösung

Obwohl die Dokumentation zu diesem Thema dürftig ist, ist es mir gelungen, durch einen Blick auf die Quelle funktionierenden Code zu erhalten.Allerdings fehlt der XML-Header, der normalerweise wichtige Informationen enthält.Hier ist ein kleines Beispielprogramm, das mit rapidxml genau das tut, was Sie suchen:

#include <iostream>
#include <sstream>
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_print.hpp"

int main(int argc, char* argv[]) {
    char xml[] = "<?xml version=\"1.0\" encoding=\"latin-1\"?>"
                 "<book>"
                 "</book>";

    //Parse the original document
    rapidxml::xml_document<> doc;
    doc.parse<0>(xml);
    std::cout << "Name of my first node is: " << doc.first_node()->name() << "\n";

    //Insert something
    rapidxml::xml_node<> *node = doc.allocate_node(rapidxml::node_element, "author", "John Doe");
    doc.first_node()->append_node(node);

    std::stringstream ss;
    ss <<*doc.first_node();
    std::string result_xml = ss.str();
    std::cout <<result_xml<<std::endl;
    return 0;
}

Andere Tipps

Verwenden print Funktion (gefunden in rapidxml_print.hpp Utility-Header), um den Inhalt des XML-Knotens in einem zu drucken stringstream.

rapidxml::print benötigt einen Ausgabeiterator, um die Ausgabe zu generieren, sodass eine Zeichenfolge damit funktioniert.Dies ist jedoch riskant, da ich nicht wissen kann, ob ein Array mit fester Länge (z. B. 2048 Bytes) lang genug ist, um den gesamten XML-Inhalt aufzunehmen.

Der richtige Weg, dies zu tun, besteht darin, einen Ausgabeiterator eines String-Streams zu übergeben, sodass der Puffer erweitert werden kann, wenn das XML darin abgelegt wird.

Mein Code ist wie folgt:

std::stringstream stream;
std::ostream_iterator<char> iter(stream);

rapidxml::print(iter, doc, rapidxml::print_no_indenting);

printf("%s\n", stream.str().c_str());
printf("len = %d\n", stream.str().size());

Wenn Sie XML selbst erstellen, vergessen Sie nicht, die Sonderzeichen zu maskieren.Dies wird häufig übersehen, kann jedoch zu ernsthaften Kopfschmerzen führen, wenn es nicht umgesetzt wird:

  • <        <
  • >        >
  • &        &
  • „        “
  • '        '

So drucken Sie einen Knoten direkt aus dem in einen String RapidXML-Handbuch:

xml_document<> doc;    // character type defaults to char
// ... some code to fill the document

// Print to stream using operator <<
std::cout << doc;   

// Print to stream using print function, specifying printing flags
print(std::cout, doc, 0);   // 0 means default printing flags

// Print to string using output iterator
std::string s;
print(std::back_inserter(s), doc, 0);

// Print to memory buffer using output iterator
char buffer[4096];                      // You are responsible for making the buffer large enough!
char *end = print(buffer, doc, 0);      // end contains pointer to character after last printed character
*end = 0;                               // Add string terminator after XML

Wenn Sie sich noch nicht für Rapid XML entschieden haben, kann ich einige alternative Bibliotheken empfehlen:

Verwenden Sie static_cast<>

Ex:

rapidxml::xml_document<> doc;
rapidxml::xml_node <> * root_node = doc.first_node();
std::string strBuff;

doc.parse<0>(xml);

.
.
.
strBuff = static_cast<std::string>(root_node->first_attribute("attribute_name")->value());

Das Folgende ist sehr einfach,

std::string s;
print(back_inserter(s), doc, 0);
cout << s;

Sie müssen lediglich den Header „rapidxml_print.hpp“ in Ihren Quellcode einfügen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top