Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Industrietechnik

Verwenden Sie die IXMLSerializable-Schnittstelle, um eine Klasse aus einer XML-Datei zu füllen

Zusammenfassung

Wussten Sie, dass die PLCnext Common Classes eine integrierte Unterstützung für die XML-Serialisierung haben? Dieser Artikel zeigt, wie man den IXmlSerializable verwendet Schnittstelle, um die Daten in einer C++-Klasse zu füllen.

Die Schnittstellenbeschreibung finden Sie in der API-Dokumentation der PLCnext Common Classes.

Anforderungen

Dieser Artikel wurde mit folgendem Setup geschrieben:

PLCnext Firmware:2020.6 LTS PLCnext C++ SDK für Linux 64 Bit 2020.6 LTS

Die Daten

Wir möchten unsere Klasse mit der folgenden Konfigurationsdatei füllen.

<?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>

Die $ARP_DATA_DIR$ Notation ist ein Platzhalter für die Umgebungsvariable, in diesem Fall ARP_DATA_DIR . Sie finden die definierten Arp-Umgebungsvariablen in Ihrer Geräteeinstellungsdatei auf dem Ziel /etc/plcnext/Device.acf.settings .

Um die Daten aus einer XML-Datei lesen zu können, müssen wir den IXMLSerializable implementieren Schnittstelle für unsere Klasse. Um es einfach zu halten, hat unsere Klasse nur zwei Datenelemente, einen DNS-Namen und einen Vektor von Dateipfaden.

#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

Implementierung

Wir müssen den ReadXml implementieren und WriteXml Methoden.

Die WriteXml Die Methode ist einfach, wir wollen nicht schreiben, wir wollen nur die Daten aus der XML-Datei lesen. Die ReadXml Die Methode wird aufgerufen, wenn wir die Daten aus der XML-Datei lesen möchten.

#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

Daten lesen

Wir können jetzt unsere Klasse mit dem XMLConfigDocument verwenden Klasse in der LoadConfig-Methode, um die Daten in unsere Klasse zu laden.

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

Industrietechnik

  1. Die Befehlszeilenschnittstelle
  2. Der zunehmende Einsatz von Technologie in der Fertigungsindustrie
  3. Java BufferedReader-Klasse
  4. Java-Dateiklasse
  5. Schnittstelle vs. abstrakte Klasse in Java:Was ist der Unterschied?
  6. Java - Schnittstellen
  7. Der vollständige Leitfaden zur Auswahl eines explosionsgeschützten Motors
  8. Verschiedene Arten der Werkzeugverwendung in der Fertigung
  9. Wozu dienen Testpunkte in einer PCB-Schaltung?
  10. Der wachsende Einsatz von Automatisierung in der Fertigung