Author of the article: Caspian
Source website: Ace Pilot_Caspian_Caspian NX secondary development 3000 examples, Caspian BlockUI column, C\C++-CSDN blog
Table of contents
3. Configure the Visual Studio development environment
7.xml_document loads the entire XML document structure
2. Read the xml file and parse it
1 Introduction
Pugixml is a lightweight, simple, and fast XML parser. The Pugixml library consists of only three files: pugixml.cpp, pugixml.hpp and pugiconfig.hpp, which is very easy to use. The parsing speed is fast and XPath expressions are supported.
2.Pugixml library
Official website download address: pugixml.org - Home
3. Configure the Visual Studio development environment
1. Create a project and set the "src" directory to "Additional Include Directories":
2. Add files
3. The code contains the header files pugiconfig.hpp and pugixml.hpp
#include <Windows.h>
#include <iostream>
#include <string>
#include <pugiconfig.hpp> //包含头文件
#include <pugixml.hpp> //包含头文件
int main()
{
std::cin.get();
return 0;
}
4.Node
The root of the tree is the document itself, which corresponds to the C++ type
xml_document
. Document subnode, corresponding to C++ typexml_node
. Nodes have different types, corresponding to C++ typesxml_attribute
5. Common node types
- Document Node (
node_document
) - This is the root of the tree and consists of multiple child nodes. This node corresponds toxml_document
a class; note that it is a subclass of , so the entire node interface is also availablexml_document
.xml_node
- Element/Tag Node (
node_element
) - This is the most common node type and represents an XML element. An element node has a name, a collection of attributes, and a collection of child nodes (both of which may be empty). This property is a simple name/value pair.- Plain character data nodes (
node_pcdata
) represent plain text in XML. PCDATA nodes have values, but no names or child nodes/properties. Note that plain character data is not part of the element node, but has its own node; for example, an element node can have multiple child PCDATA nodes.
6. Namespacepugi
All pugixml classes and functions are in a namespace
pugi
; you must use explicit name qualification (i.e.pugi::xml_node
), or access the relevant symbols via directives (i.e.using pugi::xml_node;
or ).using namespace pugi;
using
7.xml_document loads the entire XML document structure
xml_document is the owner of the entire document structure; destroying the document destroys the entire tree. The xml_document interface consists of a load function, a save function and the entire xml_node interface, allowing document inspection and/or modification.
8.xml_node document node
xml_node is a handle to a document node; it can point to any node in the document, including the document itself. All types of nodes have a common interface. Note that this is just the xml_node handle to the actual node, not the node itself - you can have multiple xml_node handles pointing to the same underlying object. Destroying the xml_node handle does not destroy the node, nor does it remove it from the tree.
xml_node has a special type value called empty node or empty node. It does not correspond to any node in any document and is therefore similar to a null pointer. However, all operations are defined on empty nodes; typically operations do nothing and return empty nodes/properties or empty strings as their results. This is useful for chaining calls; i.e., you can get the node's grandparent like this: node.parent().parent() ; if the node is an empty node or has no parent, the first parent() call returns an empty node ;Then the second parent() call also returns a null node, so you don't have to check for errors twice. You can test whether a handle is null via an implicit boolean conversion: if (node) { … } or if (!node) { … }.
9.xml_attribute attribute
xml_attribute is a handle to an XML attribute; it has the same semantics as xml_node , i.e. there can be multiple xml_attribute handles pointing to the same underlying object, and there is a special null attribute value that is propagated to the function result.
10.Examples
Example 1. Generate xml file
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <pugiconfig.hpp> //包含头文件
#include <pugixml.hpp> //包含头文件
using namespace std;
using namespace pugi;
int main()
{
// 创建一个XML文档对象
xml_document doc;
// 添加根节点
xml_node root = doc.append_child("fruits");
// 添加子节点
xml_node apple = root.append_child("fruit");
apple.append_attribute("name").set_value("苹果");
apple.append_attribute("color").set_value("红色");
apple.append_attribute("taste").set_value("甜");
xml_node banana = root.append_child("fruit");
banana.append_attribute("name").set_value("香蕉");
banana.append_attribute("color").set_value("黄色");
banana.append_attribute("taste").set_value("甜");
// 将XML内容写入文件
ofstream file("fruits.xml");
doc.save(file);
file.close();
std::cin.get();
return 0;
}
Example 2. Read xml file and parse it
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <pugiconfig.hpp> //包含头文件
#include <pugixml.hpp> //包含头文件
using namespace std;
using namespace pugi;
int main()
{
// 打开XML文件
ifstream file("fruits.xml");
// 加载XML文档
xml_document doc;
doc.load(file);
// 获取根节点
xml_node root = doc.child("fruits");
// 遍历子节点
for (xml_node fruit = root.first_child(); fruit; fruit = fruit.next_sibling()) {
// 获取属性值
string name = fruit.attribute("name").as_string();
string color = fruit.attribute("color").as_string();
string taste = fruit.attribute("taste").as_string();
// 输出属性值
cout << "Name: " << name << endl;
cout << "Color: " << color << endl;
cout << "Taste: " << taste << endl;
}
std::cin.get();
return 0;
}
Example 3. Modify xml file
Purpose: Change apples to cyan and less sweet
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <pugiconfig.hpp> //包含头文件
#include <pugixml.hpp> //包含头文件
using namespace std;
using namespace pugi;
int main()
{
// 打开XML文件
ifstream file("fruits.xml");
// 加载XML文档
xml_document doc;
doc.load(file);
// 获取根节点
xml_node root = doc.child("fruits");
// 遍历子节点
for (xml_node fruit = root.first_child(); fruit; fruit = fruit.next_sibling()) {
// 获取属性值
string name = fruit.attribute("name").as_string();
// 如果该子节点表示的是苹果
if (name == "苹果") {
// 修改属性值
fruit.attribute("color").set_value("青色");
fruit.attribute("taste").set_value("不甜");
break; // 只修改第一个匹配的节点,退出循环
}
}
// 将修改后的XML内容写入文件
ofstream outfile("fruits.xml");
doc.save(outfile);
outfile.close();
std::cin.get();
return 0;
}