2008-09-01 45 views
12

Trong chương trình C++ của tôi, tôi muốn phân tích một đoạn XML nhỏ, chèn một số nút, sau đó trích xuất XML mới (tốt nhất là std::string).
RapidXml đã được đề xuất cho tôi, nhưng tôi không thể xem cách lấy lại XML dưới dạng chuỗi văn bản.
(Tôi có thể lặp lại các nút và thuộc tính và tự xây dựng nó, nhưng chắc chắn có một chức năng xây dựng mà tôi đang thiếu.)
Cảm ơn bạn.C++: Cách trích xuất một chuỗi từ RapidXml

Trả lời

9

Althoug tài liệu kém về chủ đề này, tôi đã quản lý để lấy mã hoạt động bằng cách xem nguồn. Mặc dù thiếu tiêu đề xml thường chứa thông tin quan trọng. Dưới đây là một chương trình nhỏ ví dụ mà những gì bạn đang tìm kiếm sử dụng rapidxml:

#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; 
} 
0

Nếu bạn chưa cam kết XML nhanh, tôi có thể giới thiệu một số thư viện khác:

+0

Đừng quên vài trăm phần trăm tốc độ phạt cho các thư viện này - mặc dù cả hai đều có nhiều tính năng hơn RapidXML. –

+0

vtd-xml là một lib khác phù hợp hơn và mạnh hơn fastXML –

2

Nếu bạn tự xây dựng XML, đừng quên thoát khỏi các ký tự đặc biệt. Này có xu hướng bị bỏ qua, nhưng có thể gây ra một số đau đầu nghiêm trọng nếu nó không được thực hiện:

  • <               & lt;
  • >               & gt;
  • &               & amp;
  • "               & quot;
  • '               & apos;
6

Sử dụng print chức năng (tìm thấy trong rapidxml_print.hpp tiêu đề tiện ích) để in nội dung nút XML để một stringstream.

+0

Tuyệt vời, cho phép tôi chặn thụt lề nút – hamishmcn

+0

Bạn có thể cung cấp ví dụ không? – Qsiris

2

Dưới đây là làm thế nào để in một nút để một chuỗi thẳng từ RapidXML Manual:

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 
2

rapidxml :: in reuqires một iterator đầu ra để tạo ra sản lượng, do đó, một chuỗi ký tự làm việc với nó.Nhưng điều này là nguy hiểm vì tôi không thể biết liệu một mảng có độ dài cố định (như 2048 byte) đủ dài để chứa tất cả nội dung của XML.

Cách đúng để thực hiện điều này là chuyển qua trình lặp đầu ra của luồng chuỗi để cho phép bộ đệm được mở rộng khi XML đang được đổ vào nó.

Mã của tôi là như dưới đây:

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()); 
0

sử dụng 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()); 
0

Tiếp theo là rất dễ dàng,

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

Bạn chỉ cần bao gồm "quickxml _print.hpp "tiêu đề trong mã nguồn của bạn.

Các vấn đề liên quan