XML XPath Sample with XML Schema
With the help of the function block FB_DBRecordSelect or FB_DBRecordArraySelect it is possible to execute XPath querries select XML-Tags, XML-Subtags or XML-Attributes of any XML files. If an properly XML schema is available, the entries of the tags or attributes will be converted to the right data types.
Xou can find further information about XML-Schemes here: http://www.edition-w3.de/TR/2001/REC-xmlschema-0-20010502/
This sample demonstrate the reading of two different sub tags from a XML file with its appropriate schema.
Download "Sample with XPath and XMLSchema"
Used database type | XML |
Compatible database type | XML |
Used function blocks | FB_DBRecordSelect |
Integrated libraries | "TcDatabase.lib", "TcSystem.lib","TcBase.lib", "TcStandard.lib", "TcUtilities.lib" |
Download data list | XPath_XMLSubTag.pro, 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>
Appropriate 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_STRUCTEND_TYPE
MAIN Program
PROGRAMMAIN
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_IF
END_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_IF
END_IF
255: (* Error Step*)
;
END_CASE
Start the reading with a rising edge at the toggle variable bStartStop.