C++ 使用Poco库实现XML的读取和写入

呼延卓
2023-12-01

C++ 使用Poco库实现XML的读取和写入

flyfish


假如example.xml内容如下

<?xml version='1.0' encoding='UTF-8'?>
<!--This is comment.-->
<root_element>
	<child_element_a a1="1" a2="2"/>
	<child_element_b b1="3" b2="4"/>
</root_element>

read_xml函数实现读取该xml文件

输出结果

node:0:root_element:
node:0:child_element_a:
map:a1:1
map:a2:2
node:0:child_element_b:
map:b1:3
map:b2:4

write_xml函数实现xml文件的写入

写入文件结果

<?xml version='1.0' encoding='UTF-8'?>
<!--This is comment.-->
<root_element>
	<child_element_a a1="1" a2="2"/>
	<child_element_b b1="3" b2="4"/>
<![CDATA[ignore parse txt !@#$%^&*()]]>
<txt_element>txt_content</txt_element>
</root_element>

XML的读取和写入整体代码实现

#include <string>
#include <streambuf>
#include <sstream>
#include <iostream>
#include <Poco/AutoPtr.h> //Poco::AutoPtr
#include <Poco/DOM/Document.h> // Poco::XML::Document
#include <Poco/DOM/Element.h>  // Poco::XML::Element
#include <Poco/DOM/Text.h>       // Poco::XML::Text
#include <Poco/DOM/CDATASection.h>    // Poco::XML::CDATASection
#include <Poco/DOM/ProcessingInstruction.h> // Poco::XML::ProcessingInstruction
#include <Poco/DOM/Comment.h>  // Poco::XML::Comment
#include <Poco/DOM/DOMWriter.h> // Poco::XML::DOMWriter
#include <Poco/XML/XMLWriter.h> // Poco::XML::XMLWriter

#include <Poco/DOM/DOMParser.h>
#include <Poco/DOM/Document.h>
#include <Poco/DOM/Node.h>
#include <Poco/DOM/NamedNodeMap.h>
#include <Poco/XML/XMLString.h>
#include <Poco/XML/XMLException.h>
#include <Poco/XML/XMLStream.h>
#include <Poco/DOM/NodeIterator.h>
#include <Poco/DOM/NodeFilter.h>

void read_xml()
{
 
    Poco::XML::DOMParser parser;

    Poco::AutoPtr<Poco::XML::Document> doc = parser.parse("./example.xml");
    Poco::XML::NodeIterator it(doc, Poco::XML::NodeFilter::SHOW_ALL);//SHOW_ELEMENT SHOW_ATTRIBUTE  SHOW_TEXT  SHOW_CDATA_SECTION
    Poco::XML::Node* node = it.nextNode();

    int i=0;
    while (node)
    {
        if (node->nodeType() != Poco::XML::Node::ELEMENT_NODE)//code example
        {
            node = it.nextNode();
            continue;
        }
        if(node->nodeName() == "#text") //code example
        {
            node = it.nextNode();
            continue;
        }
        if(node->nodeName() == "#cdata-section")//code example
        {
            node = it.nextNode();
            continue;
        }

        std::cout <<"node:"<<i<<":"<<node->nodeName()<<":"<< node->nodeValue()<< std::endl;
        Poco::XML::NamedNodeMap* map = node->attributes();
        if (map)
        {
            for (size_t i = 0; i < map->length(); ++i)
            {
                Poco::XML::Node* c = map->item(i);
                std::string n1 = c->nodeName();
                std::string v1 = c->nodeValue();

                std::cout <<"map:"<<n1<<":"<<v1<< std::endl;
            }
        }
        node = it.nextNode();
    }

}

void write_xml()
{
    Poco::AutoPtr<Poco::XML::Document> doc = new Poco::XML::Document;
    //custom declaration
    Poco::AutoPtr<Poco::XML::ProcessingInstruction> pi = doc->createProcessingInstruction("xml","version='1.0' encoding='UTF-8'");
    Poco::AutoPtr<Poco::XML::Comment> comment = doc->createComment("This is comment.");
    Poco::AutoPtr<Poco::XML::Element> e_root = doc->createElement("root_element");

    Poco::AutoPtr<Poco::XML::Element> e_child_a = doc->createElement("child_element_a");
    e_child_a->setAttribute("a1", "1");
    e_child_a->setAttribute("a2", "2");

    Poco::AutoPtr<Poco::XML::Element> e_child_b = doc->createElement("child_element_b");
    e_child_b->setAttribute("b1", "3");
    e_child_b->setAttribute("b2", "4");



    Poco::AutoPtr<Poco::XML::Text> txt = doc->createTextNode("txt_content");
    Poco::AutoPtr<Poco::XML::CDATASection> cdata = doc->createCDATASection("ignore parse txt !@#$%^&*()");

    doc->appendChild(pi);
    doc->appendChild(comment);
    doc->appendChild(e_root);
    e_root->appendChild(e_child_a);
    e_root->appendChild(e_child_b);

    e_root->appendChild(cdata);
    e_root->appendChild(txt);

    Poco::XML::DOMWriter writer;

    //writer.setOptions(Poco::XML::XMLWriter::CANONICAL);
    //writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT_ATTRIBUTES); //
    //writer.setOptions(Poco::XML::XMLWriter::CANONICAL_XML);
    //writer.setOptions(Poco::XML::XMLWriter::WRITE_XML_DECLARATION);// add <?xml version='1.0' encoding='UTF-8'?>
    writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);

    writer.writeNode("./example.xml", doc);
    //string test
    std::stringstream sstr;
    writer.writeNode(sstr, doc);
    std::string s = sstr.str();
    std::cout <<s<< std::endl;
}

int main(int argc, char *argv[])
{
    write_xml();
    //read_xml();
    return 0;
}

CMakeLists.txt文件配置

cmake_minimum_required(VERSION 3.5)

project(example LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)



# set the POCO paths and libs
set(POCO_PREFIX "/usr/local") # the directory containing "include" and "lib"
set(POCO_INCLUDE_DIR"${POCO_PREFIX}/include")
set(POCO_LIB_DIR "${POCO_PREFIX}/lib")
set(POCO_LIBS
        "${POCO_LIB_DIR}/libPocoNet.so"
        "${POCO_LIB_DIR}/libPocoUtil.so"
        "${POCO_LIB_DIR}/libPocoFoundation.so"
        "${POCO_LIB_DIR}/libPocoNetSSL.so"
        "${POCO_LIB_DIR}/libPocoXML.so")


add_executable(example
  main.cpp
)
target_link_libraries(example "${POCO_LIBS}")

根据条件查找 XML 的值

假如这样的XML文件

<?xml version="1.0" encoding="UTF-8"?>
<root_node>
  <child_node ID="0">
    <person age="11" score="91"/>
  </child_node>
  <child_node ID="1">
    <person age="12" score="92"/>
  </child_node>
  <child_node ID="2">
    <person age="13" score="93"/>
  </child_node>
  <child_node ID="3">
    <person age="14" score="94"/>
  </child_node>
</root_node>

代码实现

int find_xml_value(Poco::AutoPtr<Poco::XML::Document> doc,int ID,std::string node,std::string attribute)
{
    int ret=0;

    Poco::XML::NodeIterator it(doc, Poco::XML::NodeFilter::SHOW_ALL);

    std::string s="root_node/child_node["+std::to_string(ID)+"]/"+node;"root_node/child_node[ID]/person"
    std::cout <<"1:"<<s<< std::endl;
    Poco::XML::Node* a = it.nextNode();
    Poco::XML::Node* root = a->getNodeByPath(s);

    if(root)
    {
        std::cout <<"node:"<<":"<<root->nodeName()<<":"<< root->nodeValue()<< std::endl;
        Poco::XML::NamedNodeMap* map = root->attributes();
        if (map)
        {
            for (size_t i = 0; i < map->length(); ++i)
            {
                Poco::XML::Node* c = map->item(i);
                std::string n1 = c->nodeName();
                std::string v1 = c->nodeValue();
                std::cout <<"map:"<<n1<<":"<<v1<< std::endl;
                if(n1 == attribute)
                {
                    ret=std::stoi(v1);
                    break;
                }

            }
        }
    }
    return ret;
}

int main(int argc, char *argv[])
{

    Poco::XML::DOMParser parser;
    Poco::AutoPtr<Poco::XML::Document> doc = parser.parse("./test.xml");

    int ID=2;
    std::string node="person";
    std::string attribute="score";

    int r= find_xml_value( doc, ID, node, attribute);
    std::cout <<"result:"<<r<< std::endl;

    return 0;
}
 类似资料: