Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Technologie industrielle

Utiliser l'interface IXMLSerializable pour remplir une classe à partir d'un fichier XML

Résumé

Saviez-vous que les classes communes PLCnext intègrent la prise en charge de la sérialisation XML ? Cet article montre comment utiliser le IXmlSerializable interface pour remplir les données dans une classe c++.

Vous pouvez trouver la description de l'interface dans la documentation de l'API des classes communes PLCnext.

Exigences

Cet article a été écrit avec la configuration suivante :

Micrologiciel PLCnext :2020.6 LTS SDK PLCnext C++ pour Linux 64 bits 2020.6 LTS

Les données

Nous voulons remplir notre classe avec le fichier de configuration suivant.

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

Le $ARP_DATA_DIR$ notation est un espace réservé pour la variable d'environnement, dans ce cas ARP_DATA_DIR . Vous pouvez trouver les variables d'environnement Arp définies dans le fichier de paramètres de votre appareil sur la cible /etc/plcnext/Device.acf.settings .

Pour pouvoir lire les données d'un fichier XML, nous devons implémenter le IXMLSerializable interface pour notre classe. Pour rester simple, notre classe n'a que deux éléments de données, un nom DNS et un vecteur de chemins de fichiers.

#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

Mise en œuvre

Il faut implémenter le ReadXml et WriteXml Méthodes.

Le WriteXml La méthode est simple, nous ne voulons pas écrire, nous voulons seulement lire les données du fichier XML. Le ReadXml La méthode est appelée si nous voulons lire les données du fichier 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

Lire les données

Nous pouvons maintenant utiliser notre classe avec le XMLConfigDocument classe dans la méthode LoadConfig pour charger les données dans notre classe.

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

Technologie industrielle

  1. L'interface de ligne de commande
  2. L'utilisation croissante de la technologie dans l'industrie manufacturière
  3. Classe Java BufferedReader
  4. Classe de fichier Java
  5. Interface vs classe abstraite en Java :quelle est la différence ?
  6. Java-Interfaces
  7. Le guide complet pour choisir un moteur antidéflagrant
  8. Différents types de matrices utilisées dans la fabrication
  9. Quelle est l'utilisation des points de test dans un circuit PCB ?