산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 산업기술

IXMLSerializable 인터페이스를 사용하여 XML 파일에서 클래스 채우기

추상

PLCnext Common Classes가 XML 직렬화를 지원한다는 사실을 알고 계셨습니까? 이 문서에서는 IXmlSerializable를 사용하는 방법을 보여줍니다. C++ 클래스의 데이터를 채우는 인터페이스.

PLCnext Common Classes의 API 문서에서 Interface 설명을 찾을 수 있습니다.

요구사항

이 기사는 다음 설정으로 작성되었습니다.

PLCnext 펌웨어:2020.6 LTS Linux 64비트용 PLCnext C++ SDK 2020.6 LTS

데이터

다음 구성 파일로 클래스를 채우고자 합니다.

<?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$ 표기법은 환경 변수의 자리 표시자입니다(이 경우 ARP_DATA_DIR). . 대상 /etc/plcnext/Device.acf.settings의 장치 설정 파일에서 정의된 Arp 환경 변수를 찾을 수 있습니다. .

XML 파일에서 데이터를 읽을 수 있으려면 IXMLSerializable을 구현해야 합니다. 우리 클래스의 인터페이스. 간단하게 하기 위해 우리 클래스에는 DNS 이름과 파일 경로 벡터라는 두 가지 데이터 요소만 있습니다.

#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

구현

ReadXml를 구현해야 합니다. 및 WriteXml 방법.

WriteXml 방법은 간단합니다. 우리는 XML 파일에서 데이터를 읽고 싶은 것만 쓰고 싶지 않습니다. ReadXml 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

데이터 읽기

이제 XMLConfigDocument 클래스를 사용할 수 있습니다. LoadConfig 메서드의 클래스를 사용하여 클래스의 데이터를 로드합니다.

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

산업기술

  1. 명령줄 인터페이스
  2. 제조 산업의 기술 사용 증가
  3. 자바 BufferedReader 클래스
  4. 자바 파일 클래스
  5. Java의 인터페이스 대 추상 클래스:차이점은 무엇입니까?
  6. 자바 - 인터페이스
  7. 방폭 모터 선택에 대한 전체 안내서
  8. 제조에서 다양한 유형의 다이 사용
  9. PCB 회로에서 테스트 포인트의 용도는 무엇입니까?
  10. 제조에서 자동화 사용 증가