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

C++-Klasse aus XML mit IXMLSerializable in PLCnext befüllen

Zusammenfassung

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

Die Interface-Beschreibung 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 wollen unsere Klasse mit der folgenden Konfigurationsdatei befü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 eine Umgebungsvariable, in diesem Fall ARP_DATA_DIR. Die definierten Arp-Umgebungsvariablen finden Sie in Ihrer Geräteeinstellungsdatei auf dem Target unter /etc/plcnext/Device.acf.settings.

Um Daten aus einer XML-Datei lesen zu können, müssen wir das IXMLSerializable-Interface für unsere Klasse implementieren. Zur Vereinfachung 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;
  // Die Daten
public:
  Arp::String DnsName{""};
  std::vector<Arp::String> FileList;
  // Einige Hilfsmethoden
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 die ReadXml- und WriteXml-Methoden implementieren.

Die WriteXml-Methode ist geradlinig – wir wollen nicht schreiben, sondern nur Daten aus der XML-Datei lesen. Die ReadXml-Methode wird aufgerufen, wenn wir Daten aus der XML-Datei lesen wollen.

#include "MyConfiguration.hpp"
namespace MyComponent {
void MyConfiguration::WriteXml(Arp::System::Commons::Xml::XmlWriter& writer, Arp::System::Commons::Xml::XmlSerializationContext& context) {
  // Keine 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) {
  // 'context.ResolvePath' verwenden, um Platzhalter im Pfad zu ersetzen.
  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 nun unsere Klasse mit der XMLConfigDocument-Klasse in der LoadConfig-Methode verwenden, um die Daten in unsere Klasse zu laden.

void MyComponent::LoadConfig() {
  // Projektkonfiguration hier laden
  using namespace Arp::System::Commons;
  this->log.Info("LoadConfig");
  // Erster Argument muss dem XML-Root-Elementnamen entsprechen.
  // Unsere MyConfiguration-Instanz this->config wird befüllt.
  Xml::XmlConfigDocument configDoc("MyConfigDocument", this->config);
  if (!Io::File::Exists(this->settingsPath)) {
    this->log.Error("Konfigurationsdatei '{}' existiert nicht.", this->settingsPath);
    return;
  }
  try {
    configDoc.Load(this->settingsPath);
  } catch (const Arp::Exception& e) {
    this->log.Error(e.GetMessage());
    throw InvalidConfigException(e.GetMessage());
  }
}

Industrietechnik

  1. SPICE über die Kommandozeile: Die Bedeutung des „<“-Operators
  2. Wie Technologie Fertigung transformiert: Vom 3D-Druck zu Digital Twins
  3. Java BufferedReader meistern: Effizientes Character-Stream-Handling
  4. Java-Dateioperationen mit java.io meistern – Erstellen, Lesen, Schreiben & Löschen
  5. Interface vs. Abstrakte Klasse in Java: Die richtige Abstraktion wählen
  6. Java Interfaces verstehen: Definitionen, Verwendung und Best Practices
  7. Explosionsgeschützten Motor richtig wählen: Umfassender Leitfaden
  8. Werkzeugarten in der Fertigung: Stanz-, Zieh- & Gusswerkzeuge erklärt
  9. Wie Testpunkte PCB-Tests und Produktionseffizienz verbessern
  10. Wie Automatisierung die Fertigung transformiert: Effizienz steigern & Kosten senken