首页 > 其他分享 >POCO_XML

POCO_XML

时间:2022-11-26 20:35:50浏览次数:60  
标签:XML remote runner shard servers POCO env clickhouse

POCO 简单写XML文档

参考:https://blog.csdn.net/ma52103231/article/details/7609868

先介绍一下XML文档中有哪些元素:

  • Element-文档中某个节点
  • Attr-文档中某个节点的属性
  • Text-文档中某个节点的文本
  • Comment-注释
  • ProcessingInstruction-处理信息

对于我们程序员设计网络包来说,前三个够用,起码对我目前来说。既然要用这些属性,那么我们就需要在我们的程序中包含这些头文件:

#include "Poco/DOM/Text.h"
#include "Poco/DOM/Element.h"
#include "Poco/DOM/Comment.h"
#include "Poco/DOM/ProcessingInstruction.h"
#include "Poco/DOM/Attr.h"

除此之外,POCO对文档的抽象类Document也要包含:

#include "Poco/DOM/Document.h"

必要的头文件包含之后,我们就可以动手写一个小程序了:

AutoPtr<Poco::XML::Document> pDoc = new Poco::XML::Document;
AutoPtr<Poco::XML::Element> myRoot = pDoc->createElement("Root");
AutoPtr<Poco::XML::Element> myChild = pDoc->createElement("Child");
AutoPtr<Poco::XML::Element> myGrandChild = pDoc->createElement("GrandChild");
AutoPtr<Poco::XML::Text> nameNode = pDoc->createTextNode("my_name_is_xiaoqiang");
AutoPtr<Poco::XML::ProcessingInstruction> pi = pDoc->createProcessingInstruction("xml","version='1.0' encoding='UTF-8'" );
AutoPtr<Poco::XML::Comment> comm = pDoc->createComment("new_day");

为什么 Document 前面会有 Poco::XML:: 这个东西?此东西为命名空间,POCO库中有很多命名空间,分门别类,很是醒目,所以你需要如此做。或者,你可以像 using namespace std; 一样在函数前面写上:

using Poco::XML::Document;

其他的类似。而 AutoPtr 是个智能指针类,它负责在指明的对象不用时帮你析构了,这个在POCO库中经常用到,要非常小心。

上面这些代码的作用是创建是元素,下面让我们来把他们组合成一个文档:

myGrandChild->appendChild(nameNode);
myChild->appendChild(myGrandChild);
myRoot->appendChild(myChild);
pDoc->appendChild(pi);
pDoc->appendChild(comm);
pDoc->appendChild(myRoot);

组合成文档之后,我们需要将这个文档直接写入目标文件:

DOMWriter write;
write.setOptions(XMLWriter::PRETTY_PRINT);
FileStream ofs("./example.txt",std::ios::in);
write.writeNode(ofs,pDoc);

第一句代码是创建一个写的人,他负责将文档写入文件。

第二句代码是每一个元素都在文件中另起一行,易于读者观看。

第三句代码创建一个POCO的文件流,指定目标文件和动作。

第四句代码,将数据通过流写入到文件中。

编译过程中会出错,因为DOMWriter,FileStream的头文件还没有包含呢,所以需要再包含这两个头文件。

POCO 简单读XML文档

参考:https://blog.csdn.net/ma52103231/article/details/7701880

Poco中XML各元素被抽象成的关系:

imags

可以看到,任何元素都被抽象成Node,同时又分为类型的节点。(Attr和Notation看成一种)

  1. CharacterData,这类Node是Name不可变,而Value可以由用户自定义。
  2. AbstractContainerNode,这类Node有个特点,即含有属性,特别的对于Element节点,Name可以由用户自定义,而Value不可变。
  3. 右边两个,它们既可以改变Name,也可以改变Value。

每个Element后面跟的#text内容是 \n\t(\t的个数根据文档的格式)

xml与kv相互转化

github:https://github.com/Angelia-Wang/poco_xml_to_kv

实现ClickHouse的xml配置文件的poco::xml::document对象与kv对象的相互转化。

对kv的定义:

class Item {
public:
    Item(std::string _name) : name(_name) {}
    Item() {}
    std::map<std::string, std::string> attr; // 参数的属性
    std::string name;  // 配置的参数名
    std::string value;  // 参数值
};

xml文件示例:

<clickhouse>
	<listen_host>0.0.0.0</listen_host>
	<listen_host>localhost</listen_host>

	<global_config>uncompressed_cache_size,remote_servers.shard_0.shard[0]</global_config>
	<logger>
		<level>trace</level>
		<log>/root/chdata/log/clickhouse-server/clickhouse-server.log</log>
		<size>100M</size>
	</logger>

	<uncompressed_cache_size>8589934592</uncompressed_cache_size>
	<mark_cache_size>5368709120</mark_cache_size>
	<mlock_executable>true</mlock_executable>

	<remote_servers>
		<shard_0>
			<shard c1="5">
				<replica>
					<host a1="1" a2="2">clickhouse-env-dev-ch</host>
					<port>9000</port>
				</replica>
				<replica>
					<host a3="3" a4="4">clickhouse-env-dev-ch2</host>
					<port>9000</port>
				</replica>
			</shard>
			<shard>
				<replica>
					<host b1="1" b2="2">clickhouse-env-runner-0.clickhouse-env-runner</host>
					<port>9000</port>
				</replica>
				<replica>
					<host b3="3" b4="4">clickhouse-env-runner-0.clickhouse-env-runner2</host>
					<port>9000</port>
				</replica>
			</shard>
		</shard_0>
		<shard_1>
			<shard>
				<replica>
					<host>clickhouse-env-runner-0.clickhouse-env-runner</host>
					<port>9000</port>
				</replica>
			</shard>
			<shard>
				<replica>
					<host>clickhouse-env-runner-1.clickhouse-env-runner</host>
					<port>9000</port>
				</replica>
			</shard>
		</shard_1>
	</remote_servers>
</clickhouse>

示例转成的kv对象:

name:value

​ attr_name:attr_value

listen_host[0]:0.0.0.0
listen_host[1]:localhost
global_config:uncompressed_cache_size,remote_servers.shard_0.shard[0]
logger.level:trace
logger.log:/root/chdata/log/clickhouse-server/clickhouse-server.log
logger.size:100M
uncompressed_cache_size:8589934592
mark_cache_size:5368709120
mlock_executable:true
remote_servers.shard_0.shard[0]:
    c1:5
remote_servers.shard_0.shard[0].replica[0].host:clickhouse-env-dev-ch
    a1:1
    a2:2
remote_servers.shard_0.shard[0].replica[0].port:9000
remote_servers.shard_0.shard[0].replica[1].host:clickhouse-env-dev-ch2
    a3:3
    a4:4
remote_servers.shard_0.shard[0].replica[1].port:9000
remote_servers.shard_0.shard[1].replica[0].host:clickhouse-env-runner-0.clickhouse-env-runner
    b1:1
    b2:2
remote_servers.shard_0.shard[1].replica[0].port:9000
remote_servers.shard_0.shard[1].replica[1].host:clickhouse-env-runner-0.clickhouse-env-runner2
    b3:3
    b4:4
remote_servers.shard_0.shard[1].replica[1].port:9000
remote_servers.shard_1.shard[0].replica.host:clickhouse-env-runner-0.clickhouse-env-runner
remote_servers.shard_1.shard[0].replica.port:9000
remote_servers.shard_1.shard[1].replica.host:clickhouse-env-runner-1.clickhouse-env-runner
remote_servers.shard_1.shard[1].replica.port:9000

此处kv对象的name符合 Poco/Util/XMLConfiguration.h 中对name的格式,通过 has 方法能判断name对应的参数在xml文件中是否存在。

using ConfigurationPtr = Poco::AutoPtr<Poco::Util::AbstractConfiguration>;
if (configuration->has(name)){
  ...
}

通过Poco::XML::Document的 getNodeByPath 方法,能得到 Document 对象中对应 path 的 Node 结点。

name 和 path 对应关系举例:

  • name = remote_servers.shard_1.shard[0].replica.host
  • path = remote_servers/shard_1/shard[0]/replica/host

标签:XML,remote,runner,shard,servers,POCO,env,clickhouse
From: https://www.cnblogs.com/angelia-wang/p/16928236.html

相关文章