如何用Boost C++删除所有Book节点下的Price XML子节点?
问题
我是Boost XML parser新手,需要删除示例中每个Book节点下的Price子节点。目前已成功删除所有Book节点的Author子节点,但只能删除一个Book节点的Price子节点,输出显示仅处理了一个Book,请问如何实现删除所有Book节点的Price子节点?
原代码
#include <iostream> #include <boost/foreach.hpp> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/detail/ptree_utils.hpp> int main() { std::istringstream iss(R"( <BookData> <Book><Author>A1</Author><Name>B1</Name><Config><Price>C1</Price><Model>M1</Model></Config></Book> <Book><Author>A2</Author><Name>B2</Name><Config><Price>C2</Price><Model>M2</Model></Config></Book> <Book><Author>A(n-1)</Author><Name>B(n-1)</Name><Config><Price>C(n-1)</Price><Model>M3</Model></Config></Book> <Book><Author>A(n)</Author><Name>B(n)</Name><Config><Price>C(n)</Price><Model>M4</Model></Config></Book> </BookData> )"); boost::property_tree::ptree pt; read_xml(iss, pt); for (auto& node : pt.get_child("BookData")) { std::cout << "Child node of BookData: " << node.first << std::endl; node.second.erase("Author"); } for (auto& node : pt.get_child("BookData.Book")) { std::cout << "Child node of Book: " << node.first << std::endl; if(node.first == "Config" ) { std::cout << "Erasing Price" << std::endl; node.second.erase("Price"); } } write_xml(std::cout, pt, boost::property_tree::xml_writer_make_settings<std::string>(' ', 4)); }
原输出结果
Child node of BookData: Book Child node of BookData: Book Child node of BookData: Book Child node of BookData: Book Child node of Book: Name Child node of Book: Config Erasing Price <?xml version="1.0" encoding="utf-8"?> <BookData> <Book> <Name>B1</Name> <Config> <Model>M1</Model> </Config> </Book> <Book> <Name>B2</Name> <Config> <Price>C2</Price> <Model>M2</Model> </Config> </Book> <Book> <Name>B(n-1)</Name> <Config> <Price>C(n-1)</Price> <Model>M3</Model> </Config> </Book> <Book> <Name>B(n)</Name> <Config> <Price>C(n)</Price> <Model>M4</Model> </Config> </Book> </BookData>
解决方案
核心问题是:pt.get_child("BookData.Book")只会获取第一个Book节点的子节点,无法遍历所有Book。
正确的做法是复用删除Author时的遍历逻辑——先遍历BookData下的所有Book节点,再针对每个Book节点找到Config子节点并删除Price:
修改后的代码:
#include <iostream> #include <boost/foreach.hpp> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/detail/ptree_utils.hpp> int main() { std::istringstream iss(R"( <BookData> <Book><Author>A1</Author><Name>B1</Name><Config><Price>C1</Price><Model>M1</Model></Config></Book> <Book><Author>A2</Author><Name>B2</Name><Config><Price>C2</Price><Model>M2</Model></Config></Book> <Book><Author>A(n-1)</Author><Name>B(n-1)</Name><Config><Price>C(n-1)</Price><Model>M3</Model></Config></Book> <Book><Author>A(n)</Author><Name>B(n)</Name><Config><Price>C(n)</Price><Model>M4</Model></Config></Book> </BookData> )"); boost::property_tree::ptree pt; read_xml(iss, pt); // 删除所有Book的Author节点 for (auto& node : pt.get_child("BookData")) { std::cout << "Child node of BookData: " << node.first << std::endl; node.second.erase("Author"); } // 遍历所有Book节点,删除每个Book下Config中的Price for (auto& book_node : pt.get_child("BookData")) { if (book_node.first == "Book") { auto& config_node = book_node.second.get_child("Config"); std::cout << "Erasing Price from Book" << std::endl; config_node.erase("Price"); } } write_xml(std::cout, pt, boost::property_tree::xml_writer_make_settings<std::string>(' ', 4)); }
修改后运行,所有Book节点下的Price都会被删除,每个Book的Config节点中只会保留Model子节点。
内容的提问来源于stack exchange,提问作者Taylor swift
相关产品推荐
相关产品推荐

