Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Teknologi Industri

Gunakan antarmuka IXMLSerializable untuk mengisi kelas dari file XML

Abstrak

Tahukah Anda bahwa Kelas Umum PLCnext telah mendukung serialisasi XML? Artikel ini menunjukkan cara menggunakan IXmlSerializable antarmuka untuk mengisi data dalam kelas c++.

Anda dapat menemukan deskripsi Antarmuka dalam dokumentasi API Kelas Umum PLCnext.

Persyaratan

Artikel ini ditulis dengan pengaturan berikut:

PLCnext Firmware:2020.6 LTS PLCnext C++ SDK untuk Linux 64 Bit 2020.6 LTS

Data

Kami ingin mengisi kelas kami dengan file konfigurasi berikut.

<?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$ notasi adalah placeholder untuk variabel lingkungan, dalam hal ini ARP_DATA_DIR . Anda dapat menemukan variabel lingkungan Arp yang ditentukan dalam file pengaturan perangkat Anda pada target /etc/plcnext/Device.acf.settings .

Untuk dapat membaca data dari file XML kita harus mengimplementasikan IXMLSerializable antarmuka untuk kelas kami. Untuk membuatnya tetap sederhana, kelas kami hanya memiliki dua elemen data, nama DNS dan vektor jalur file.

#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

Implementasi

Kita harus menerapkan ReadXml dan WriteXml Metode.

WriteXml Metodenya lurus ke depan, kami tidak ingin menulis kami hanya ingin membaca data dari file XML. ReadXml Metode dipanggil jika kita ingin membaca data dari file 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

Baca data

Kita sekarang dapat menggunakan kelas kita dengan XMLConfigDocument class di Metode LoadConfig untuk memuat data di kelas kita.

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());
    }
}

Teknologi Industri

  1. Antarmuka Baris Perintah
  2. Meningkatnya Penggunaan Teknologi di Industri Manufaktur
  3. Kelas Java BufferedReader
  4. Kelas File Java
  5. Antarmuka vs Kelas Abstrak di Jawa:Apa Perbedaannya?
  6. Java - Antarmuka
  7. Panduan Lengkap Memilih Motor Tahan Ledakan
  8. Berbagai Jenis Penggunaan Die dalam Manufaktur
  9. Apa Penggunaan Titik Uji di Sirkuit PCB?
  10. Meningkatnya Penggunaan Otomatisasi dalam Manufaktur