C++ programımda küçük bir XML parçasını ayrıştırmak, bazı düğümleri eklemek ve sonra yeni XML'yi (tercihen std::string
olarak) ayıklamak istiyorum.
RapidXml bana önerildi, ancak XML'i bir metin dizesi olarak nasıl geri alacağımı göremiyorum.
(Düğümler ve öznitelikler üzerinde yinelemeli ve bunu kendim yapılandırabilirim, ancak kesinlikle eksik olduğum işlevler var).
Teşekkür ederiz. Henüz Rapid XML taahhüt değilsenizC++: RapidXml'den bir dize nasıl çıkarılır
cevap
Bu konudaki belgeler yetersiz olduğundan, kaynağa bakarak bazı çalışma kodlarını almayı başardım. Normalde önemli bilgiler içeren xml başlığını eksik olsa da.
#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;
}
, bazı alternatif kütüphaneler tavsiye edebilir:
Xerces - Bu muhtemelen defacto C++ uygulamasıdır.
XMLite - Bu minimal XML uygulamasında biraz şansım oldu. XML kendini inşa yoksa http://www.codeproject.com/KB/recipes/xmlite.aspx
de makalesine bakın, özel karakterler kaçmayı unutma. Bu göz ardı eğilimindedir, ancak uygulanmadı, bazı ciddi baş ağrılarına neden olabilir:
- < & lt;
- > & gt;
- & & amp;
- " & quot;
- ' & l'-
Kullanım print
fonksiyonu (rapidxml_print.hpp
yarar başlığındaki bulunan) bir stringstream
XML düğümü içeriğini yazdırmak için: Burada rapidxml kullanarak aradığınızı yapan küçük bir örnek programdır.
İşte RapidXML Manual düz bir dizeye bir düğüm yazdırmak için:
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
rapidxml :: baskı çıktısı üreten bir çıkış yineleyici reuqires, böylece bir karakter dizesi onunla çalışır.Ancak bu risklidir çünkü sabit uzunluğa (2048 bayt gibi) sahip bir dizinin XML'nin tüm içeriğini tutmak için yeterince uzun olup olmadığını bilmem.
Bunu yapmanın doğru yolu, bir dize akışının bir çıktı yineleyicisini iletmektir, böylece XML'ye dökülürken arabelleğin genişletilmesine izin verin.
std::string s;
print(back_inserter(s), doc, 0);
cout << s;
Sadece gerekir
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());
Kullanım <>
Ör static_cast:
Kodum aşağıda gibidir "rapidxml dahil et Kaynak kodunuzda _print.hpp "başlığı.
ardından çok kolaydır:
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());
Sadece bu kütüphaneler için yüzde yüz yüzde cezayı unutmayın - her ikisinin de RapidXML'den çok daha fazla özelliği var. –
vtd-xml, daha hızlı ve daha güçlü olan bir daha fazla lib olan fastXML –