XPath-Beispiel mit XML-Schema
Mithilfe des Funktionsbausteins FB_DBRecordSelect oder FB_DBRecordArraySelect können XPath‑Kommandos abgesetzt 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: TcDBSrv_InfoSysSamples.zip
Verwendeter Datenbanktyp | XML |
Kompatible Datenbanktypen | XML |
Verwendete Funktionsbausteine | FB_DBRecordSelect |
Einzubindende Bibliotheken | Tc2_Database, Tc2_System, Tc2_Standard, Tc2_Utilities |
Download Dateiliste | TcDBSrv_InfoSysSamples.tszip, 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_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
Mit einer positiven Flanke an der Toggle-Variable „bStartStop“ wird das Auslesen gestartet.
Voraussetzungen
Entwicklungsumgebung | Zielplattform | Einzubindende SPS Bibliotheken |
---|---|---|
TwinCAT v3.0.0 | PC oder CX (x86) | Tc2_Database |