XML Datenbanktyp - XPath Beispiel mit XML-Schema
Mit Hilfe des Funktionsbausteins FB_DBRecordSelect oder FB_DBRecordArraySelect können XPath Kommandos abgesetzt werden und XML-Tags, XML-Subtags oder XML-Attribute aus einer beliebigen XML Datei gelesen werden. Ist ein passendes XML-Schema für die zu lesende XML-Datei vorhanden, werden die Inhalte der Tags bzw. Attribute in die entsprechenden Datentypen konvertiert, so wie sie in dem Schema definiert sind.
Nähere Informationen zu XML-Schemas finden Sie hier: http://www.edition-w3.de/TR/2001/REC-xmlschema-0-20010502/
In diesem Beispiel werden mit dem FB_DBRecordArraySelect zwei unterschiedliche Subtags aus einer XML-Datei mit zugehörigem XML-Schema ausgelesen.
Download "Beispiel mit XPath und XMLSchema" sample11.zip

Verwendeter Datenbanktyp | XML |
Kompatible Datenbanktypen | XML |
Verwendete Funktionsbausteine | FB_DBRecordSelect |
Einzubindende Bibliotheken | "TcDatabase.lib", "TcSystem.lib", "TcBase.lib", "STANDARD.lib", "TcUtilities.lib" |
Download Dateiliste | XPath_XMLSubTag.pro, CurrentConfigDatabase.xml, PLC_Structs.xml, PLC_Structs.xsd |
Beispiel XML-Datei (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>
Zugehöriges 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>
Struktur1 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
Struktur2 ST_TestStruct2
TYPE ST_TestStruct2 :
STRUCT
sSTRING : T_MaxString;
bBOOL : BOOL;
nINT32 : DINT;
END_STRUCT
END_TYPE
MAIN Programm
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_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
Mit einer Positiven Flanke an der Toggle Variable bStartStop wird das Auslesen gestartet.
