XPath sample with XML schema

The function blocks FB_DBRecordSelect or FB_DBRecordArraySelect can be used to issue XPath commands and to read XML tags, XML subtags or XML attributes from any XML file. If a suitable XML schema exists for the XML file to be read, the content of the tags or attributes is converted to the corresponding data types, as defined in the schema.

Further information about XML schemas can be found here: http://www.edition-w3.de/TR/2001/REC-xmlschema-0-20010502/

In this sample, FB_DBRecordArraySelect is used to read two different subtags from an XML file with corresponding XML schema.

Download: TcDBSrv_InfoSysSamples.zip

XPath sample with XML schema 1:

Database type used

XML

Compatible database types

XML

Function blocks used

FB_DBRecordSelect

Libraries to be integrated

Tc2_Database, Tc2_System, Tc2_Standard, Tc2_Utilities

Download file list

TcDBSrv_InfoSysSamples.tszip, CurrentConfigDatabase.xml, PLC_Structs.xml, PLC_Structs.xsd

Sample XML file (PLC_Structs.xml)

<?xml version = "1.0" encoding="utf-8" ?>
<Beckhoff_PLC>
  <PLC_Structs>
    <PLC_Struct Name="ST_TestStruct">
      <Struct Instance="1">
        <nINT64>123456789</nINT64>
        <nUINT16>1234</nUINT16>
        <rREAL64>1234.5678</rREAL64>
        <sSTRING>This is instance one of ST_TestStruct</sSTRING>
        <bBOOL>true</bBOOL>
        <nINT32>-100</nINT32>
      </Struct>
      <Struct Instance="2">
        <nINT64>234567890</nINT64>
        <nUINT16>2345</nUINT16>
        <rREAL64>234.56789</rREAL64>
        <sSTRING>This is instance two of ST_TestStruct</sSTRING>
        <bBOOL>false</bBOOL>
        <nINT32>-50</nINT32>
      </Struct>
      <Struct Instance="3">
        <nINT64>345678901</nINT64>
        <nUINT16>3456</nUINT16>
        <rREAL64>3456.78901</rREAL64>
        <sSTRING>This is instance three of ST_TestStruct</sSTRING>
        <bBOOL>true</bBOOL>
        <nINT32>-150</nINT32>
      </Struct>
    </PLC_Struct>
    <PLC_Struct Name="ST_TestStruct2">
      <Struct2 Instance="1">
        <sSTRING>This is instance one of ST_TestStruct2</sSTRING>
        <bBOOL>false</bBOOL>
        <nINT32>-88</nINT32>
      </Struct2>
      <Struct2 Instance="2">
        <sSTRING>This is instance two of ST_TestStruct2</sSTRING>
        <bBOOL>true</bBOOL>
        <nINT32>-9</nINT32>
      </Struct2>
    </PLC_Struct>
  </PLC_Structs>
</Beckhoff_PLC>

Corresponding XML schema (PLC_Structs.xsd)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Beckhoff_PLC">
    <xs:complexType >
      <xs:sequence >
        <xs:element name = "PLC_Structs">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs = "unbounded" name="PLC_Struct">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element minOccurs = "0" maxOccurs="unbounded" name="Struct">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name = "nINT64" type="xs:long" />
                          <xs:element name = "nUINT16" type="xs:unsignedShort" />
                          <xs:element name = "rREAL64" type="xs:double" />
                          <xs:element name = "sSTRING" type="xs:string" />
                          <xs:element name = "bBOOL" type="xs:boolean" />
                          <xs:element name = "nINT32" type="xs:int" />
                        </xs:sequence>
                        <xs:attribute name = "Instance" type="xs:unsignedByte" use="required" />
                      </xs:complexType>
                    </xs:element>
                    <xs:element minOccurs = "0" maxOccurs="unbounded" name="Struct2">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name = "sSTRING" type="xs:string" />
                          <xs:element name = "bBOOL" type="xs:boolean" />
                          <xs:element name = "nINT32" type="xs:int" />
                        </xs:sequence>
                        <xs:attribute name = "Instance" type="xs:unsignedByte" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name = "Name" type="xs:string" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Structure1 ST_TestStruct

TYPE ST_TestStruct :
STRUCT
    nINT64 : T_LARGE_INTEGER;
    nUINT16: UINT;
    rREAL64: LREAL;
    sSTRING: T_MaxString;
    bBOOL  : BOOL;
    nINT32 : DINT;
END_STRUCT
END_TYPE 

Structure2 ST_TestStruct2

TYPE ST_TestStruct2 :
STRUCT
    sSTRING: T_MaxString;
    bBOOL  : BOOL;
    nINT32 : DINT;
END_STRUCT
END_TYPE 

MAIN program

PROGRAM MAIN
VAR
 nState                 : BYTE;

 R_TRIG1                : R_TRIG;
 bStartStop             : BOOL;

 sCmd                   : T_MaxString;

 FB_DBRecordArraySelect1: FB_DBRecordArraySelect;
 arrTestStruct          : ARRAY [0..3] OF ST_TestStruct;
 arrTestStruct2         : ARRAY [0..3] OF ST_TestStruct2;

 bBusy                  : BOOL;
 bError                 : BOOL;
 nErrID                 : UDINT;
 stSQLState             : ST_DBSQLError;

 nRecs1                 : UDINT;
 nRecs2                 : UDINT;
END_VAR 
R_TRIG1(CLK:=bStartStop);
IF R_TRIG1.Q THEN
 FB_DBRecordArraySelect1(bExecute:=FALSE);
 nState                 := 1;
END_IF
CASE nState OF
 0:(*Idle*)
 ;
 1:
 sCmd:='XPATH<SUBTAG>#/Beckhoff_PLC/PLC_Structs/PLC_Struct[@Name=$'ST_TestStruct$']/Struct';

 FB_DBRecordArraySelect1(
     sNetID            := ,
     hDBID             := 1,
     cbCmdSize         := SIZEOF(sCmd),
     pCmdAddr          := ADR(sCmd),
     nStartIndex       := 0,
     nRecordCount      := 4,
     cbRecordArraySize := SIZEOF(arrTestStruct),
     pDestAddr         := ADR(arrTestStruct),
     bExecute          := TRUE,
     tTimeout          := T#15s,
     bBusy              => bBusy,
     bError             => bError,
     nErrID             => nErrID,
     sSQLState          => stSQLState,
     nRecords           => nRecs1);

 IF NOT bBusy THEN
    FB_DBRecordArraySelect1(bExecute:=FALSE);
    IF NOT bError THEN
     nState            := 2;
    ELSE
     nState            := 255;
    END_IFEND_IF
 2:
 sCmd:='XPATH<SUBTAG>#Beckhoff_PLC/PLC_Structs/PLC_Struct[@Name=$'ST_TestStruct2$']/Struct2';

 FB_DBRecordArraySelect1(
     sNetID            := ,
     hDBID             := 1,
     cbCmdSize         := SIZEOF(sCmd),
     pCmdAddr          := ADR(sCmd),
     nStartIndex       := 0,
     nRecordCount      := 4,
     cbRecordArraySize := SIZEOF(arrTestStruct2),
     pDestAddr         := ADR(arrTestStruct2),
     bExecute          := TRUE,
     tTimeout          := T#15s,
     bBusy              => bBusy,
     bError             => bError,
     nErrID             => nErrID,
     sSQLState          => stSQLState,
     nRecords           => nRecs2);

 IF NOT bBusy THEN
    FB_DBRecordArraySelect1(bExecute:=FALSE);
    IF NOT bError THEN
     nState            := 0;
    ELSE
     nState            := 255;
    END_IFEND_IF
 255: (* Error Step*)
 ;
END_CASE 

Reading is started with a positive edge at the toggle variable "bStartStop".

XPath sample with XML schema 2:

Requirements

Development environment

Target platform

PLC libraries to be linked

TwinCAT v3.0.0

PC or CX (x86)

Tc2_Database