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

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".
Requirements
Development environment |
Target platform |
PLC libraries to be linked |
---|---|---|
TwinCAT v3.0.0 |
PC or CX (x86) |
Tc2_Database |