Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Tecnología Industrial

Use la interfaz IXMLSerializable para completar una clase desde un archivo XML

Resumen

¿Sabía que las clases comunes de PLCnext tienen compatibilidad integrada con la serialización XML? Este artículo muestra cómo usar el IXmlSerializable interfaz para llenar los datos en una clase c++.

Puede encontrar la descripción de la interfaz en la documentación de la API de las clases comunes de PLCnext.

Requisitos

Este artículo fue escrito con la siguiente configuración:

Firmware PLCnext:2020.6 LTS PLCnext C++ SDK para Linux 64 bits 2020.6 LTS

Los datos

Queremos llenar nuestra clase con el siguiente archivo de configuración.

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

El $ARP_DATA_DIR$ la notación es un marcador de posición para la variable de entorno, en este caso ARP_DATA_DIR . Puede encontrar las variables de entorno Arp definidas en el archivo de configuración de su dispositivo en el destino /etc/plcnext/Device.acf.settings .

Para poder leer los datos de un archivo XML tenemos que implementar el IXMLSerializable interfaz para nuestra clase. Para mantenerlo simple, nuestra clase tiene solo dos elementos de datos, un nombre DNS y un vector de rutas de archivos.

#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

Implementación

Debemos implementar el ReadXml y WriteXml Métodos.

El WriteXml El método es sencillo, no queremos escribir, solo queremos leer los datos del archivo XML. El ReadXml Se llama al método si queremos leer los datos del archivo 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

Leer los datos

Ahora podemos usar nuestra clase con el XMLConfigDocument class en el Método LoadConfig para cargar los datos en nuestra clase.

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

Tecnología Industrial

  1. La interfaz de línea de comandos
  2. El uso cada vez mayor de la tecnología en la industria manufacturera
  3. Clase Java BufferedReader
  4. Clase de archivo Java
  5. Interfaz vs clase abstracta en Java:¿cuál es la diferencia?
  6. Java - Interfaces
  7. La guía completa para elegir un motor a prueba de explosiones
  8. Diferentes tipos de uso de troqueles en la fabricación
  9. ¿Cuál es el uso de los puntos de prueba en un circuito de PCB?
  10. El uso creciente de la automatización en la fabricación
  11. ¿Por qué utilizar Realidad Aumentada en la industria?