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"

XML XPath Sample with XML Schema 1:

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.

XML XPath Sample with XML Schema 2: