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

XML Datenbanktyp - XPath Beispiel mit XML-Schema 1:

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.

XML Datenbanktyp - XPath Beispiel mit XML-Schema 2: