亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 工业技术

使用 IXMLSerializable 接口从 XML 文件填充类

摘要

您知道 PLCnext 公共类内置了对 XML 序列化的支持吗?本文介绍如何使用 IXmlSerializable 在 c++ 类中填充数据的接口。

接口说明可以在PLCnext Common Classes的API文档中找到。

要求

本文是使用以下设置编写的:

PLCnext 固件:2020.6 LTS PLCnext C++ SDK for Linux 64 Bit 2020.6 LTS

数据

我们想用以下配置文件填充我们的类。

<?xml version="1.0" encoding="UTF-8"?>
<MyConfigDocument schemaVersion="1.0">
    <Server dnsName="server.domain.tld" />
    <FileList>
        <File path="$ARP_DATA_DIR$/Services/MyComponent/file1.txt" />
        <File path="$ARP_DATA_DIR$/Services/MyComponent/file2.txt" />
    </FileList>
</MyConfigDocument>

$ARP_DATA_DIR$ notation 是环境变量的占位符,在本例中为 ARP_DATA_DIR .您可以在目标 /etc/plcnext/Device.acf.settings 上的设备设置文件中找到已定义的 Arp 环境变量 .

为了能够从 XML 文件中读取数据,我们必须实现 IXMLSerializable 我们类的接口。为了简单起见,我们的类只有两个数据元素,一个 DNS 名称和一个文件路径向量。

#pragma once
#include "Arp/System/Core/Arp.h"
#include "Arp/System/Commons/Xml/IXmlSerializable.hpp"
#include "vector"

namespace MyComponent
{

class MyConfiguration : public Arp::System::Commons::Xml::IXmlSerializable
{
public:
    MyConfiguration() = default;
    ~MyConfiguration() = default;

// IXMLSerializable interface
public:
    void ReadXml(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context) override;
    void WriteXml(Arp::System::Commons::Xml::XmlWriter& writer, Arp::System::Commons::Xml::XmlSerializationContext& context) override;

// The data
public:
    Arp::String DnsName{""};
    std::vector<Arp::String> FileList;

// Some supporting methods
private:
    void readFileList(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context);
    void readFile(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context);
};

} // namespace MyComponent

实现

我们必须实现 ReadXmlWriteXml 方法。

WriteXml 方法很简单,我们不想写我们只想从 XML 文件中读取数据。 ReadXml 如果我们想从 XML 文件中读取数据,则调用方法。

#include "MyConfiguration.hpp"

namespace MyComponent
{ 

void MyConfiguration::WriteXml(Arp::System::Commons::Xml::XmlWriter& writer, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
    // no operation.
    return;
}

void MyConfiguration::ReadXml(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
    Arp::String elementName;
    while (reader.TryReadStartElement(elementName))
    {
        if (elementName == Arp::System::Commons::Xml::XmlSerializationContext::IncludesXmlName)
        {
            context.ReadIncludesElement(reader);
        }
        else if (elementName == "Server")
        {
            this->DnsName = reader.GetAttributeValue<Arp::String>("dnsName");
            reader.ReadEndElement();
        }
        else if (elementName == "FileList")
        {
            this->readFileList(reader, context);
        }
        else
        {
            context.InvalidXmlElementOccurs(reader, elementName);
            reader.ReadEndElement();
        }
    }
}

void MyConfiguration::readFileList(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
    if (reader.IsEmptyElement()){
        return;
    }
    if (reader.ReadToDescendant("File"))
    {
        this->readFile(reader, context);
        while (reader.ReadToNextSibling("File"))
        {
            this->readFile(reader, context);
        }
    }
    else
    {
        reader.ReadEndElement();
    }
}

void MyConfiguration::readFile(Arp::System::Commons::Xml::XmlReader& reader, Arp::System::Commons::Xml::XmlSerializationContext& context)
{
    // Use 'context.ResolvePath' to replace placeholders in the path.
    auto file = Arp::String(context.ResolvePath(reader.GetAttributeValue<Arp::String>("path")));
    this->FileList.push_back(file);
    reader.ReadEndElement();
}

} // namespace MyComponent

读取数据

我们现在可以将我们的类与 XMLConfigDocument 一起使用 类中的LoadConfig方法来加载我们类中的数据。

void MyComponent::LoadConfig()
{
    // load project config here

    using namespace Arp::System::Commons;

    this->log.Info("LoadConfig");

    // Fist argument has to match the XML root element name.
    // Our MyConfiguration instance this->config will be populated.
    Xml::XmlConfigDocument configDoc("MyConfigDocument", this->config);
    if (!Io::File::Exists(this->settingsPath))
    {
        this->log.Error("Configuration file '{}' does not exist.", this->settingsPath);
        return;
    }

    try
    {
        configDoc.Load(this->settingsPath);
    }
    catch (const Arp::Exception& e)
    {
        this->log.Error(e.GetMessage());
        throw InvalidConfigException(e.GetMessage());
    }
}

工业技术

  1. 命令行界面
  2. 了解数字孪生在制造业中的使用
  3. 制造业中越来越多地使用技术
  4. Java BufferedReader 类
  5. Java 文件类
  6. Java中的接口与抽象类:有什么区别?
  7. Java - 接口
  8. 选择防爆电机的完整指南
  9. 制造中使用不同类型的模具
  10. PCB电路中测试点的用途是什么?
  11. 制造业中越来越多地使用自动化
  12. 为什么在行业中使用增强现实?