XPath sample to illustrate the different SELECT types
The function block FB_DBRecordArraySelect/FB_DBRecordSelect can be used to issue XPath commands and read XML tags from any XML file. This sample illustrates reading of different entries from XML files via the TwinCAT Database Server. Individual tags, subtags and reading of attributes is supported, and these are displayed.
Download: TcDBSrv_InfoSysSamples.zip
Database type used | XML |
Compatible database types | XML |
Function blocks used | FB_DBRecordArraySelect |
Libraries to be integrated | Tc2_Database, Tc2_System, Tc2_Standard, Tc2_Utilities |
Download file list | TcDBSrv_InfoSysSamples.tszip |
Sample XML file (XMLFactoryXY.xml)
<?xmlversion="1.0" encoding="utf-8" ?>
<Factory_XY>
<Name>Sample Factory XY</Name>
<Factory_Info>
<Street>Samplestreet 25</Street>
<City>33415 Verl</City>
<Country>Germany</Country>
<Office_Count>1</Office_Count>
<Employe_Count>6</Employe_Count>
<Manager>Max Mustermann</Manager>
</Factory_Info>
<Employees>
<Employeeid="10001" name="Julia Kingston" department="Development" position="Worker" hired="2001-08-01" />
<Employeeid="10002" name="Jens Marx" department="Import" position="Worker" hired="2003-08-01" />
<Employeeid="10003" name="Justus Kaiser" department="Export" position="Worker" hired="2003-08-01" />
<Employeeid="10004" name="Marc Klein" department="Production" position="Worker" hired="2005-08-01" />
<Employeeid="10005" name="Matt Bloomberg" department="Production" position="Worker" hired="2005-08-01" />
<Employeeid="10006" name="Frida Hundt" department="Production" position="Worker" hired="2010-08-01" />
</Employees>
</Factory_XY>
ST_FactoryInfo structure
TYPEST_FactoryInfo :
STRUCT
sStreet : T_MaxString;
sCity : T_MaxString;
sCountry : T_MaxString;
sOffice_Count : T_MaxString;
sEmploye_Count: T_MaxString;
sManager : T_MaxString;
END_STRUCT
END_TYPE
ST_Employee structure
TYPEST_Employee :
STRUCT
sID : T_MaxString;
sName : T_MaxString;
sDepartment : T_MaxString;
sPosition : T_MaxString;
sHired : T_MaxString;
END_STRUCT
END_TYPE
MAIN program
PROGRAM MAIN
VAR
bSTART : BOOL;
R_TRIG1 : R_TRIG;
nState : INT;
sXPath : T_MaxString;
fbDBRecordArraySelect : FB_DBRecordArraySelect;
bBusy_ReadFactoryName : BOOL;
bError_ReadFactoryName: BOOL;
nErrID_ReadFactoryName: UDINT;
bBusy_ReadFactoryInfo : BOOL;
bError_ReadFactoryInfo: BOOL;
nErrID_ReadFactoryInfo: UDINT;
bBusy_ReadEmployee : BOOL;
bError_ReadEmployee : BOOL;
nErrID_ReadEmployee : UDINT;
stSQLState : ST_DBSQLError;
sFactoryName : T_MaxString;
stFactoryInfo : ST_FactoryInfo;
aEmployees : ARRAY [1..10] OF ST_Employee;
END_VAR
R_TRIG1(CLK:=bSTART);
IF R_TRIG1.Q THEN
bSTART:=FALSE;
fbDBRecordArraySelect(bExecute:=FALSE);
nState:=1;
END_IF
CASE nState OF
0://IDLE
;
1://Read Factory Name
sXPath:= 'XPATH#Factory_XY/Name';
fbDBRecordArraySelect(
sNetID := ,
hDBID := 7,
pCmdAddr := ADR(sXPath),
cbCmdSize := SIZEOF(sXPath),
nStartIndex := 0,
nRecordCount := 1,
pDestAddr := ADR(sFactoryName),
cbRecordArraySize:= SIZEOF(sFactoryName),
bExecute := TRUE,
tTimeout := T#15S,
bBusy => bBusy_ReadFactoryName,
bError => bError_ReadFactoryName,
nErrID => nErrID_ReadFactoryName,
sSQLState => stSQLState,
nRecords => );
IF NOT bBusy_ReadFactoryName THEN
fbDBRecordArraySelect(bExecute:=FALSE);
IF NOT bError_ReadFactoryName THEN
nState :=2;
ELSE
nState :=255;
END_IFEND_IF
2://Read Factory Info
sXPath := 'XPATH#Factory_XY/Factory_Info';
fbDBRecordArraySelect(
sNetID := ,
hDBID := 7,
pCmdAddr := ADR(sXPath),
cbCmdSize := SIZEOF(sXPath),
nStartIndex := 0,
nRecordCount := 1,
pDestAddr := ADR(stFactoryInfo),
cbRecordArraySize := SIZEOF(stFactoryInfo),
bExecute := TRUE,
tTimeout := T#15S,
bBusy => bBusy_ReadFactoryInfo,
bError => bError_ReadFactoryInfo,
nErrID => nErrID_ReadFactoryInfo,
sSQLState => stSQLState,
nRecords => );
IF NOT bBusy_ReadFactoryInfo THEN
fbDBRecordArraySelect(bExecute:=FALSE);
IF NOT bError_ReadFactoryInfo THEN
nState :=3;
ELSE
nState :=255;
END_IF
END_IF
3://Read Employees
sXPath := 'XPATH#Factory_XY/Employees/Employee';
fbDBRecordArraySelect(
sNetID := ,
hDBID := 7,
pCmdAddr := ADR(sXPath),
cbCmdSize := SIZEOF(sXPath),
nStartIndex := 0,
nRecordCount := 10,
pDestAddr := ADR(aEmployees),
cbRecordArraySize := SIZEOF(aEmployees),
bExecute := TRUE,
tTimeout := T#15S,
bBusy => bBusy_ReadEmployee,
bError => bError_ReadEmployee,
nErrID => nErrID_ReadEmployee,
sSQLState => stSQLState,
nRecords => );
IF NOT bBusy_ReadEmployee THEN
fbDBRecordArraySelect(bExecute:=FALSE);
IF NOT bError_ReadEmployee THEN
nState :=0;
ELSE
nState :=255;
END_IFEND_IF
255://Error State
;
END_CASE
A positive edge at the variable "bStart" triggers issuing of the XPath commands and reading of the individual elements from the XML file. The results will then be in the variables "sFactoryName", "stFactoryInfo" and "aEmployees".
Requirements
Development environment |
Target platform |
PLC libraries to be linked |
---|---|---|
TwinCAT v3.0.0 |
PC or CX (x86) |
Tc2_Database |