--- a +++ b/branch/xmlresultformatter/XmlResultFormatter-OpenPLC.xml @@ -0,0 +1,2142 @@ +<?xml version="1.0" encoding="utf-8"?> +<project xmlns="http://www.plcopen.org/xml/tc6_0200"> + <fileHeader companyName="" productName="CODESYS" productVersion="CODESYS V3.5 SP15" creationDateTime="2019-12-26T21:10:01.304469" /> + <contentHeader name="XmlResultFormatter.project" modificationDateTime="2019-12-26T20:38:04.3246887"> + <coordinateInfo> + <fbd> + <scaling x="1" y="1" /> + </fbd> + <ld> + <scaling x="1" y="1" /> + </ld> + <sfc> + <scaling x="1" y="1" /> + </sfc> + </coordinateInfo> + <addData> + <data name="http://www.3s-software.com/plcopenxml/projectinformation" handleUnknown="implementation"> + <ProjectInformation> + <property name="CompiledLibraryCompatibilityVersion" type="string">CODESYS V3.5 SP14 Patch 2</property> + <property name="Project" type="string">XmlResultFormatter</property> + </ProjectInformation> + </data> + </addData> + </contentHeader> + <types> + <dataTypes> + <dataType name="E_XmlError"> + <baseType> + <enum> + <values> + <value name="Ok" value="0" /> + <value name="ErrorMaxBufferLen" value="1" /> + <value name="ErrorStringLen" value="2" /> + <value name="Error" value="3" /> + </values> + <baseType> + <BYTE /> + </baseType> + </enum> + </baseType> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="qualified_only" Value="" /> + <Attribute Name="strict" Value="" /> + </Attributes> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>05a4fdda-1086-47b5-ad10-7c2bac568355</ObjectId> + </data> + </addData> + </dataType> + <dataType name="T_MaxString"> + <baseType> + <string length="255" /> + </baseType> + <addData> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>a429e267-db3b-4872-871e-1ca509b971e2</ObjectId> + </data> + </addData> + </dataType> + </dataTypes> + <pous> + <pou name="prg_Example" pouType="program"> + <interface> + <localVars> + <variable name="XmlPac"> + <type> + <derived name="FB_XmlPac" /> + </type> + </variable> + <variable name="XmlFileFormatter"> + <type> + <derived name="FB_XmlFileFormatter" /> + </type> + </variable> + <variable name="xUnitFileComposer"> + <type> + <derived name="I_TestResultFormatter" /> + </type> + <initialValue> + <simpleValue value="XmlFileFormatter" /> + </initialValue> + </variable> + <variable name="BusyGeneratingXml"> + <type> + <BOOL /> + </type> + </variable> + <variable name="DoneGeneratingXml"> + <type> + <BOOL /> + </type> + </variable> + <variable name="NumberOfTestSuitesFinished"> + <type> + <UINT /> + </type> + <initialValue> + <simpleValue value="3" /> + </initialValue> + </variable> + <variable name="NumberOfTestCases"> + <type> + <UINT /> + </type> + <initialValue> + <simpleValue value="9" /> + </initialValue> + </variable> + <variable name="NumberOfSuccessfulTestCases"> + <type> + <UINT /> + </type> + <initialValue> + <simpleValue value="0" /> + </initialValue> + </variable> + <variable name="NumberOfFailedTestCases"> + <type> + <UINT /> + </type> + <initialValue> + <simpleValue value="9" /> + </initialValue> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">XmlPac(); + +IF NOT DoneGeneratingXml THEN + xUnitFileComposer.Format(NumberOfTestSuites := NumberOfTestSuitesFinished, + NumberOfTestCases := NumberOfTestCases, + NumberOfSuccessfulTestCases := NumberOfSuccessfulTestCases, + NumberOfFailedTestCases := NumberOfFailedTestCases, + Busy => BusyGeneratingXml); + DoneGeneratingXml := NOT BusyGeneratingXml; +END_IF;</xhtml> + </ST> + </body> + <addData> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>917c49f4-3643-42fe-b791-ac2edc0df35b</ObjectId> + </data> + </addData> + </pou> + <pou name="FB_XmlFileFormatter" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="stFileAccessMode"> + <type> + <derived name="SysFile.ACCESS_MODE" /> + </type> + <initialValue> + <simpleValue value="SysFile.AM_WRITE_PLUS" /> + </initialValue> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Default file access mode </xhtml> + </documentation> + </variable> + </inputVars> + <localVars> + <variable name="szFilename"> + <type> + <string /> + </type> + <initialValue> + <simpleValue value="''" /> + </initialValue> + </variable> + <variable name="xBufferInitialised"> + <type> + <BOOL /> + </type> + <initialValue> + <simpleValue value="FALSE" /> + </initialValue> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Is buffer Initialised? </xhtml> + </documentation> + </variable> + <variable name="File"> + <type> + <derived name="FB_FileControl" /> + </type> + </variable> + <variable name="Xml"> + <type> + <derived name="FB_XmlControl" /> + </type> + </variable> + <variable name="Buffer"> + <type> + <string length="GVL_Param_XmlControl.MaxFileSize" /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Buffer : ARRAY [0..GVL_Param_XmlControl.MaxFileSize-1] OF BYTE; + Or</xhtml> + </documentation> + </variable> + </localVars> + <addData> + <data name="http://www.3s-software.com/plcopenxml/pouinheritance" handleUnknown="implementation"> + <Inheritance> + <Implements>I_TestResultFormatter</Implements> + </Inheritance> + </data> + </addData> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + This function block reports the results from the tests into a xUnit compatible XmlFile +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml" /> + </ST> + </body> + <addData> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Format" ObjectId="b6b6021c-eac1-4ed2-91cd-9954fbe29c28"> + <interface> + <inputVars> + <variable name="NumberOfTestSuites"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test suites </xhtml> + </documentation> + </variable> + <variable name="NumberOfTestCases"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test cases (for all test function blocks) </xhtml> + </documentation> + </variable> + <variable name="NumberOfSuccessfulTestCases"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test cases that had all ASSERTS successful </xhtml> + </documentation> + </variable> + <variable name="NumberOfFailedTestCases"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test cases that had at least one ASSERT failed </xhtml> + </documentation> + </variable> + </inputVars> + <localVars> + <variable name="SuiteCounter"> + <type> + <UINT /> + </type> + </variable> + <variable name="TestCounter"> + <type> + <UINT /> + </type> + </variable> + <variable name="TestSuiteName"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + <variable name="NumberOfFailedTestsInCurrentSuite"> + <type> + <UINT /> + </type> + </variable> + <variable name="NumberOfTestsInCurrentSuite"> + <type> + <UINT /> + </type> + </variable> + <variable name="TestCaseName"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + <variable name="AssertResult"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </localVars> + <outputVars> + <variable name="Busy"> + <type> + <BOOL /> + </type> + </variable> + </outputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Responsible for formatting the xml file skeleton + <testsuites> => the aggregated result OF all xunit testfiles + <testsuite> => the output from a single TestSuite + <properties> => the defined properties at test execution + <property> => name/value pair for a single property + ... + </properties> + <error></error> => optional information, in place of a test case - normally if the tests in the suite could not be found etc. + <testcase> => the results from executing a test method + <system-out> => data written to System.out during the test run + <system-err> => data written to System.err during the test run + <skipped/> => test was skipped + <failure> => test failed + <error> => test encountered an error + </testcase> + ... + </testsuite> + ... + </testsuites></xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Busy := TRUE; + +NumberOfTestsInCurrentSuite := 3; + +IF NumberOfFailedTestCases > 0 THEN + LOGSTR(msgCtrlMask := UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), + msgFmtStr := '%s', + strArg := '| ========= Export Xml Report ========='); + + (* <?xml version="1.0" encoding="UTF-8"?> *) + Xml.writeDocumentHeader(Header := '<?xml version="1.0" encoding="UTF-8"?>'); + xml.NewTag('testsuites'); + FOR SuiteCounter := 1 TO NumberOfTestSuites BY 1 DO + (* <testsuite> *) + xml.NewTag('testsuite'); + + (* name="name" *) + //TestSuiteInstancePath := 'TestInstancePath' + TestSuiteName := 'TestSuiteName'; + Xml.NewParameter('name', TestSuiteName); + + (* <testsuite errors="errors"> *) + //NumberOfFailedTestsInCurrentSuite := UINT_TO_STRING(NumberOfFailedTestCases); + Xml.NewParameter('errors', UINT_TO_STRING(NumberOfFailedTestsInCurrentSuite)); + + (* <testsuite errors="errors" tests="tests">*) + + Xml.NewParameter('tests', UINT_TO_STRING(NumberOfTestsInCurrentSuite)); + + (* close testsuite *) + Xml.CloseTag(); + + FOR TestCounter := 1 TO NumberOfTestsInCurrentSuite BY 1 DO + + //IF GVL_CfUnit.TestSuiteAddresses[SuiteCounter]^.Tests[TestCounter].IsFailed() THEN + IF TRUE THEN + + (* get testcase name *) + //TestCaseName := GVL_CfUnit.TestSuiteAddresses[SuiteCounter]^.Tests[TestCounter].GetName(); + TestCaseName := 'TestCaseName'; + Xml.NewTag('testcase'); + Xml.NewParameter('name', TestCaseName); + (* close testcase *) + Xml.CloseTag(); + + Xml.NewTag('failure'); + //AssertResult := GVL_CfUnit.TestSuiteAddresses[SuiteCounter]^.AssertResults.AssertResults[TestCounter]; + //Xml.NewParameter('message', AssertResult.Message ); + Xml.NewParameter('message', 'AssertResultMessage' ); + Xml.NewTagData('Assertion failed'); + (* close failure *) + Xml.CloseTag(); + END_IF + END_FOR + END_FOR + + (* Close testsuites *) + Xml.CloseTag(); + + (* Open, save and close the file *) + OpenSaveAndClose(); +END_IF + +Busy := FALSE;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="FB_Init" ObjectId="0f23c47b-7245-415e-b489-0ae429217263"> + <interface> + <returnType> + <BOOL /> + </returnType> + <inputVars> + <variable name="bInitRetains"> + <type> + <BOOL /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> TRUE: the retain variables are initialized (reset warm / reset cold)</xhtml> + </documentation> + </variable> + <variable name="bInCopyCode"> + <type> + <BOOL /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> TRUE: the instance will be copied to the copy code afterward (online change)</xhtml> + </documentation> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml">FB_Init is always available implicitly and it is used primarily for initialization. +The return value is not evaluated. For a specific influence, you can also declare the +methods explicitly and provide additional code there with the standard initialization +code. You can evaluate the return value.</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">// Set Filepath +szFilename := GVL_Param_XmlControl.FilePath; +// Set buffer and flag +Xml.SetBuffer(pString := ADR(Buffer), iSizeOf := SIZEOF(Buffer)); +xBufferInitialised := TRUE;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="OpenSaveAndClose" ObjectId="bdefa095-3448-4b85-b486-ff4d5205677b"> + <interface> + <returnType> + <BOOL /> + </returnType> + <addData> + <data name="http://www.3s-software.com/plcopenxml/accessmodifiers" handleUnknown="implementation"> + <AccessModifiers Private="true" /> + </data> + </addData> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">// write buffer to a file +File.Open(Filename := szFilename, FileAccessMode := stFileAccessMode); +File.Save(pString := ADR(Buffer), xml.Length ); +File.Close(); + +Xml.ClearBuffer();</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>6597c0b3-0890-4d5d-8d3a-2d0d0b2355db</ObjectId> + </data> + </addData> + </pou> + <pou name="FB_FileControl" pouType="functionBlock"> + <interface> + <localVars> + <variable name="FileAccessMode"> + <type> + <derived name="SysFile.ACCESS_MODE" /> + </type> + <initialValue> + <simpleValue value="SysFile.AM_WRITE_PLUS" /> + </initialValue> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="hide" Value="" /> + </Attributes> + </data> + </addData> + </variable> + <variable name="FileHandle"> + <type> + <derived name="SysFile.SysTypes.RTS_IEC_HANDLE" /> + </type> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="hide" Value="" /> + </Attributes> + </data> + </addData> + </variable> + </localVars> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="hide_all_locals" Value="" /> + </Attributes> + </data> + </addData> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml" /> + </ST> + </body> + <addData> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Close" ObjectId="519e9011-283c-40b1-afd4-31686c5b81fe"> + <interface> + <returnType> + <derived name="SysFile.SysTypes.RTS_IEC_RESULT" /> + </returnType> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Closes the current file</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF FileHandle <> SysFile.SysTypes.RTS_INVALID_HANDLE THEN + Close := SysFile.SysFileClose(hFile := FileHandle); +END_IF</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Open" ObjectId="1873bb2c-c6a3-4681-8948-02aa2bad0a9b"> + <interface> + <returnType> + <derived name="SysFile.SysTypes.RTS_IEC_RESULT" /> + </returnType> + <inputVars> + <variable name="FileName"> + <type> + <derived name="T_MaxString" /> + </type> + <initialValue> + <simpleValue value="'filepath/output.xml'" /> + </initialValue> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> File name can contain an absolute or relative path to the file. Path entries must be separated with a Slash (/)</xhtml> + </documentation> + </variable> + <variable name="FileAccessMode"> + <type> + <derived name="SysFile.ACCESS_MODE" /> + </type> + <initialValue> + <simpleValue value="SysFile.ACCESS_MODE.AM_APPEND_PLUS" /> + </initialValue> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Opens a file</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">FileHandle := SysFile.SysFileOpen(szFile := Filename, + am := FileAccessMode, + pResult := ADR(Open));</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Read" ObjectId="3984ae50-1cdb-4045-af99-0bb56917afb2"> + <interface> + <returnType> + <derived name="SysFile.SysTypes.RTS_IEC_RESULT" /> + </returnType> + <inputVars> + <variable name="pString"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Call with ADR();</xhtml> + </documentation> + </variable> + <variable name="Size"> + <type> + <UDINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Call with SIZEOF(); </xhtml> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="FileSize"> + <type> + <derived name="SysFile.SysTypes.RTS_IEC_SIZE" /> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF FileHandle <> SysFile.SysTypes.RTS_INVALID_HANDLE THEN + FileSize := SysFile.SysFileread(hFile := FileHandle, + pbyBuffer := pString, + ulSize := Size, + pResult := ADR(Read)); +END_IF</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Save" ObjectId="c4146a99-50c6-4ce0-88ab-794dbfb1af62"> + <interface> + <returnType> + <derived name="SysFile.SysTypes.RTS_IEC_RESULT" /> + </returnType> + <inputVars> + <variable name="pString"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Call with ADR();</xhtml> + </documentation> + </variable> + <variable name="Size"> + <type> + <UDINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Call with SIZEOF();</xhtml> + </documentation> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Saves the contents of the buffer into a file + Be sure to call Open() before calling Save()</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF FileHandle <> SysFile.SysTypes.RTS_INVALID_HANDLE THEN + SysFile.SysFileWrite(hFile := FileHandle, + pbyBuffer := pString, + ulSize := Size, + pResult := ADR(Save)); +END_IF</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>c9bec8fc-2de3-45f4-b839-e6c4276a6b5a</ObjectId> + </data> + </addData> + </pou> + <pou name="FB_StreamBuffer" pouType="functionBlock"> + <interface> + <localVars> + <variable name="pStrBuf"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="udiBufSize"> + <type> + <UDINT /> + </type> + </variable> + <variable name="udiLength"> + <type> + <UDINT /> + </type> + </variable> + </localVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + This functionblock acts as a stream buffer for use with FB_XmlControl +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml" /> + </ST> + </body> + <addData> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Clear" ObjectId="5f0bbce2-2600-4a2e-8c6f-4b957ad03395"> + <interface> + <localVars> + <variable name="i"> + <type> + <UDINT /> + </type> + </variable> + </localVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Clears the buffer and sets the length to 0</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF (pStrBuf = 0) OR (udiBufsize = 0) THEN + RETURN; +END_IF + +FOR i := 0 TO (udiBufsize-1) DO + pStrBuf[i] := 0; +END_FOR + +udiLength := 0; </xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Copy" ObjectId="b796dd60-63f5-4b75-acc5-8fa40e24be46"> + <interface> + <returnType> + <derived name="T_MaxString" /> + </returnType> + <inputVars> + <variable name="udiStart"> + <type> + <UDINT /> + </type> + </variable> + <variable name="udiEnd"> + <type> + <UDINT /> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="udiCopyLen"> + <type> + <UDINT /> + </type> + </variable> + <variable name="XmlError"> + <type> + <derived name="E_XmlError" /> + </type> + </variable> + </outputVars> + <localVars> + <variable name="udiLoop"> + <type> + <UDINT /> + </type> + </variable> + <variable name="pByteCopy"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pByteBuffer"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + </localVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Copies a string from the character buffer +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">udiLoop := 0; +pByteCopy := ADR(Copy); +pByteBuffer := pStrBuf + udiStart - 1; + +WHILE(udiLoop < SIZEOF(Copy)) AND udiStart - 1 + udiLoop < udiLength AND udiStart + udiLoop < udiEnd DO + pByteCopy^ := pByteBuffer^; + udiLoop := udiLoop + 1; + pByteCopy := ADR(Copy) + udiLoop; + pByteBuffer := pStrBuf + udiStart + udiLoop -1; +END_WHILE; + +IF udiLoop = SIZEOF(Copy) THEN + XmlError := E_XmlError.ErrorStringLen; +ELSIF udiStart - 1 + udiLoop = udiLength THEN + XmlError := E_XmlError.ErrorMaxBufferLen; +ELSE + XmlError := E_XmlError.OK; +END_IF; + +pByteCopy^ := 0; +udiCopyLen := udiLoop;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="CutOff" ObjectId="8914e4f8-8b6c-48c3-ba1f-e0642038624a"> + <interface> + <returnType> + <string /> + </returnType> + <inputVars> + <variable name="udiStartPos"> + <type> + <UDINT /> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="udiCutLen"> + <type> + <UDINT /> + </type> + </variable> + <variable name="XmlError"> + <type> + <derived name="E_XmlError" /> + </type> + </variable> + </outputVars> + <localVars> + <variable name="iLoop"> + <type> + <UDINT /> + </type> + </variable> + <variable name="pByteCut"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pByteBuffer"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">iLoop := 0; +pByteCut := ADR(CutOff); +pByteBuffer := pStrBuf + udiStartPos - 1; + +WHILE pByteBuffer^ <> 0 AND(iLoop < SIZEOF(CutOff)) AND udiStartPos -1 + iLoop < udiLength DO + pByteCut^ := pByteBuffer^; + iLoop := iLoop + 1; + pByteCut := ADR(CutOff) + iLoop; + pByteBuffer := pStrBuf + udiStartPos - 1 + iLoop; +END_WHILE; + +IF pByteBuffer^ = 0 THEN + XmlError := E_XmlError.OK; +ELSIF iLoop = SIZEOF(CutOff) THEN + XmlError := E_XmlError.ErrorStringLen; +ELSIF udiStartPos -1 + iLoop = udiLength THEN + XmlError := E_XmlError.ErrorMaxBufferLen; +END_IF; + +pByteCut^ := 0; +udiLength := udiStartPos -1; + +pByteBuffer := pStrBuf + udiStartPos - 1; +pByteBuffer^ := 0; + +udiCutLen := iLoop;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Find" ObjectId="7e38490a-9555-451d-957e-fef284a567e3"> + <interface> + <returnType> + <UDINT /> + </returnType> + <inputVars> + <variable name="sSearchString"> + <type> + <string /> + </type> + </variable> + <variable name="udiStartPos"> + <type> + <UDINT /> + </type> + </variable> + </inputVars> + <localVars> + <variable name="udiLoop"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSearch"> + <type> + <UDINT /> + </type> + </variable> + <variable name="pBuffer"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pSearch"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + </localVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Find a searchstring in the buffer and returns its position. + It's possible to add a preffered startposition within buffer +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">udiLoop := 0; +iSearch := 0; + +pBuffer := pStrBuf + udiStartPos; +pSearch := ADR( sSearchString); + +WHILE(pSearch^ <> 0 ) AND udiLoop + udiStartPos < udiLength DO + IF pBuffer^ <> pSearch^ THEN + udiLoop := udiLoop + 1; + pBuffer := pStrBuf + udiStartPos + udiLoop; + pSearch := ADR( sSearchString); + iSearch := 0; + ELSE + iSearch := iSearch +1; + pBuffer := pStrBuf + udiStartPos + udiLoop + iSearch; + pSearch := ADR( sSearchString ) + iSearch; + END_IF; +END_WHILE; +Find := udiLoop + 1 + udiStartPos;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="FindBack" ObjectId="7d08b204-2078-4fde-81eb-e04d71986196"> + <interface> + <returnType> + <UDINT /> + </returnType> + <inputVars> + <variable name="sSearchString"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </inputVars> + <localVars> + <variable name="udiLoop"> + <type> + <UDINT /> + </type> + </variable> + <variable name="udiSearch"> + <type> + <UDINT /> + </type> + </variable> + <variable name="pBuffer"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pSearch"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">udiLoop := 0; +udiSearch := 0; + +pBuffer := pStrBuf + udiLength; +pSearch := ADR(sSearchString); + +WHILE(pSearch^ <> 0 ) AND udiLoop < udiLength DO + IF pBuffer^ <> pSearch^ THEN + udiLoop := udiLoop + 1; + pBuffer := pStrBuf + udiLength - udiLoop; + pSearch := ADR( sSearchString); + udiSearch := 0; + ELSE + udiSearch := udiSearch + 1; + pBuffer := pStrBuf + udiLength - udiLoop + udiSearch; + pSearch := ADR( sSearchString ) + udiSearch; + END_IF; +END_WHILE; +FindBack := udiLength - udiLoop + 1;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="Set" ObjectId="59092938-ca22-4896-8f54-1c854a0bd883"> + <interface> + <returnType> + <BOOL /> + </returnType> + <inputVars> + <variable name="pbyAdr"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Set buffer adress (ADR ...)</xhtml> + </documentation> + </variable> + <variable name="udiSize"> + <type> + <UDINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Set buffer size (SIZEOF ...)</xhtml> + </documentation> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Sets the Buffer </xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF (pbyAdr = 0) OR (udiSize = 0) THEN + Set := FALSE; + RETURN; +END_IF; + +udiBufSize := udiSize; +pStrBuf := pbyAdr; + +Set := TRUE;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/property" handleUnknown="implementation"> + <Property name="Append" ObjectId="ddd7c0b6-46f9-4fa9-946e-0da608268245"> + <interface> + <returnType> + <derived name="T_MaxString" /> + </returnType> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Appends a string to the buffer</xhtml> + </documentation> + </interface> + <SetAccessor> + <interface> + <localVars> + <variable name="pByteIn"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pByteBuffer"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">pByteIn := ADR(Append); +pByteBuffer := pStrBuf + udiLength; + +WHILE pByteIn^ <> 0 AND (udiLength < udiBufSize ) DO + pByteBuffer^ := pByteIn^; + udiLength := udiLength + 1; + pByteIn := pByteIn + 1; + pByteBuffer := pByteBuffer + 1; +END_WHILE; + +pByteBuffer := pStrBuf + udiLength; (* String End *) +pByteBuffer^ := 0; (* null terminated string *) +</xhtml> + </ST> + </body> + <addData /> + </SetAccessor> + <addData /> + </Property> + </data> + <data name="http://www.3s-software.com/plcopenxml/property" handleUnknown="implementation"> + <Property name="BufferSize" ObjectId="879a667c-416e-4879-91ff-6641233ded93"> + <interface> + <returnType> + <UDINT /> + </returnType> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Read current Buffersize</xhtml> + </documentation> + </interface> + <GetAccessor> + <interface /> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">BufferSize := udiBufSize;</xhtml> + </ST> + </body> + <addData /> + </GetAccessor> + <addData /> + </Property> + </data> + <data name="http://www.3s-software.com/plcopenxml/property" handleUnknown="implementation"> + <Property name="Length" ObjectId="80c3b0fb-2bdc-4829-89c6-017e171b31eb"> + <interface> + <returnType> + <UDINT /> + </returnType> + </interface> + <GetAccessor> + <interface /> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Length := udiLength;</xhtml> + </ST> + </body> + <addData /> + </GetAccessor> + <SetAccessor> + <interface /> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">udiLength := Length;</xhtml> + </ST> + </body> + <addData /> + </SetAccessor> + <addData /> + </Property> + </data> + <data name="http://www.3s-software.com/plcopenxml/property" handleUnknown="implementation"> + <Property name="Prepend" ObjectId="c4fdd2db-7736-4bc5-a06f-ba3a29618794"> + <interface> + <returnType> + <derived name="T_MaxString" /> + </returnType> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Prepends a string to the buffer</xhtml> + </documentation> + </interface> + <SetAccessor> + <interface> + <localVars> + <variable name="TempBuf"> + <type> + <string length="GVL_Param_XmlControl.MaxFileSize" /> + </type> + </variable> + <variable name="pTempBuf"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pByteIn"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="pByteBuffer"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="i"> + <type> + <UDINT /> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">//save current buffer to temporary buffer +pByteBuffer := pStrBuf; + +FOR i := 0 TO (udiBufsize-1) DO + TempBuf[i] := pByteBuffer[i]; +END_FOR + +pByteIn := ADR(Prepend); +pByteBuffer := pStrBuf; + +WHILE pByteIn^ <> 0 AND (udiLength < udiBufSize ) DO + pByteBuffer^ := pByteIn^; + udiLength := udiLength + 1; + pByteIn := pByteIn + 1; + pByteBuffer := pByteBuffer + 1; +END_WHILE; + +pTempBuf := ADR(TempBuf); +WHILE pTempBuf^ <> 0 AND (udiLength < udiBufSize ) DO + pByteBuffer^ := pTempBuf^; + pTempBuf := pTempBuf + 1; + pByteBuffer := pByteBuffer + 1; +END_WHILE; + +pByteBuffer := pStrBuf + udiLength; (* String End *) +pByteBuffer^ := 0; (* nul terminated string *) +</xhtml> + </ST> + </body> + <addData /> + </SetAccessor> + <addData /> + </Property> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>fbccbed5-94ee-455b-a9d5-e8b750ed732e</ObjectId> + </data> + </addData> + </pou> + <pou name="FB_XmlControl" pouType="functionBlock"> + <interface> + <localVars> + <variable name="Buffer"> + <type> + <derived name="FB_StreamBuffer" /> + </type> + </variable> + <variable name="TagList"> + <type> + <derived name="FB_StreamBuffer" /> + </type> + </variable> + <variable name="sTags"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + <variable name="TagListSeek"> + <type> + <derived name="FB_StreamBuffer" /> + </type> + </variable> + <variable name="sTagsSeek"> + <type> + <string /> + </type> + </variable> + <variable name="Tag"> + <type> + <derived name="FB_StreamBuffer" /> + </type> + </variable> + <variable name="sTag"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + <variable name="xTagOpen"> + <type> + <BOOL /> + </type> + </variable> + <variable name="iSelect"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectStart"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectEnd"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectStartPara"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectEndPara"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectTagClose"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectStartValue"> + <type> + <UDINT /> + </type> + </variable> + <variable name="iSelectEndValue"> + <type> + <UDINT /> + </type> + </variable> + <variable name="udiSearchPos"> + <type> + <UDINT /> + </type> + </variable> + </localVars> + <localVars constant="true"> + <variable name="TAG_OPEN"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="'<'" /> + </initialValue> + </variable> + <variable name="TAG_CLOSE"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="'>'" /> + </initialValue> + </variable> + <variable name="END_TAG_CLOSE"> + <type> + <string length="4" /> + </type> + <initialValue> + <simpleValue value="'/>'" /> + </initialValue> + </variable> + <variable name="SPACE"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="' '" /> + </initialValue> + </variable> + <variable name="EQUALS"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="'='" /> + </initialValue> + </variable> + <variable name="QUOTE"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="'"'" /> + </initialValue> + </variable> + <variable name="BACK_SLASH"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="'\'" /> + </initialValue> + </variable> + <variable name="FORWARD_SLASH"> + <type> + <string length="1" /> + </type> + <initialValue> + <simpleValue value="'/'" /> + </initialValue> + </variable> + <variable name="OPEN_COMMENT"> + <type> + <string length="5" /> + </type> + <initialValue> + <simpleValue value="'<!-- '" /> + </initialValue> + </variable> + <variable name="CLOSE_COMMENT"> + <type> + <string length="4" /> + </type> + <initialValue> + <simpleValue value="' -->'" /> + </initialValue> + </variable> + <variable name="TAB"> + <type> + <string length="2" /> + </type> + <initialValue> + <simpleValue value="'$T'" /> + </initialValue> + </variable> + <variable name="CR_LF"> + <type> + <string length="4" /> + </type> + <initialValue> + <simpleValue value="'$R$N'" /> + </initialValue> + </variable> + </localVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> +Organizes parsing and composing of XML data. Data can be treated as STRING or char array. +Filebuffersize is default 4096 bytes and can be set via Gvl_Param_XmlControl + +Usage example: + +1. Initiate + VAR + XML : FB_XMLControl; + Buffer: STRING(GVL_Param_XmlControl.udiMaxFileSize); + //or + Buffer: ARRAY [0..GVL_Param_XmlControl.udiMaxFileSize] OF BYTE; + END_VAR + + XML.pBuffer: = ADR (buffer); + XML.LenBuffer: = SIZEOF (buffer); + + Add your own preferred fileheader like so: + XML: <?xml version="1.0" encoding="UTF-8"?> + + XML.WriteDocumentHeader( '<?xml version="1.0" encoding="UTF-8"?>'); + +2. Compose a tag with a parameters: +XML: <MyTag ParaName = "11" /> + + XML.newTag(sTagName: = 'MyTag'); + XML.newPara(sName: = 'ParaName', sPara: = sValue); + XML.CloseTag(); + + +3. Add tag value: +XML: <MyTag> MyText </ MyTag> + + XML.newTag(sName := 'MyTag'); + XML.newTagData(sTagData :='MyText'); + XML.CloseTag(); + + +4. Jump to the beginning of the XML data +XML.toStartBuffer(); + + +5. Add a comment: +XML: <!-- MyComment --> + + XML.newComment(sTagName: = 'MyComment'); + +6. Returns the next tag from the current position in buffer +XML.NextTag(); + + +7. Output the parameter of the tag +XML.NextPara(sPara: = LastValue); +Feedback: sPara returns the value found (string) + +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml" /> + </ST> + </body> + <addData> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="NewTag" ObjectId="c44bdbda-725a-4943-a5cc-fa5ea9485541"> + <interface> + <inputVars> + <variable name="Name"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Creates a new Tag: + XML: <MyTag> + + XML.NewTag(Name: = 'MyTag'); +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF xTagOpen THEN + Buffer.Append := TAG_CLOSE; +END_IF; +Buffer.Append := TAG_OPEN; +Buffer.Append := Name; +xTagOpen := TRUE; +TagList.Append := FORWARD_SLASH; +TagList.Append := Name;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="ClearBuffer" ObjectId="651b4460-232e-47e8-95ba-ecea1541fbb9"> + <interface> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Clears the contents of the entire buffer +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">udiSearchPos := 0; +TagListSeek.Length := 0; +Buffer.Length := 0; +sTagsSeek := ''; +sTag := '';</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="CloseTag" ObjectId="eedd2aac-2425-4325-8128-bfe1e984f3f7"> + <interface> + <returnType> + <derived name="T_MaxString" /> + </returnType> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Closes a Tag: + XML: <MyTag />' + + Method: XML.CloseTag(); +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF xTagOpen THEN + Buffer.Append := END_TAG_CLOSE; + iSelect := TagList.FindBack(sSearchString := FORWARD_SLASH); + CloseTag := TagList.CutOff(udiStartPos:= iSelect); + xTagOpen := FALSE; +ELSE + iSelect := TagList.FindBack(sSearchString := FORWARD_SLASH); + CloseTag := TagList.CutOff(udiStartPos:= iSelect); + Buffer.Append := TAG_OPEN; + Buffer.Append := CloseTag; + Buffer.Append := TAG_CLOSE; +END_IF</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="NewComment" ObjectId="0f41fa45-b92e-4e7e-b2b3-ecb5d5918326"> + <interface> + <inputVars> + <variable name="Comment"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Adds a comment; + XML: <!-- MyComment --> + + XML.NewComment(Comment: = 'MyComment'); +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">IF xTagOpen THEN + Buffer.Append := TAG_CLOSE; + xTagOpen := FALSE; +END_IF; +Buffer.Append := OPEN_COMMENT; +Buffer.Append := Comment; +Buffer.Append := CLOSE_COMMENT;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="NewParameter" ObjectId="60c10606-ff09-4f9b-a3dd-0b54d0f565c7"> + <interface> + <inputVars> + <variable name="Name"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + <variable name="Value"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Must be called after opening a new tag + + XML.NewParameter(Name: = 'ParaName', Value: = 'Value'); +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Buffer.Append := SPACE; +Buffer.Append := Name; +Buffer.Append := EQUALS; +Buffer.Append := QUOTE; +Buffer.Append := Value; +Buffer.Append := QUOTE;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="NewTagData" ObjectId="e4679d3f-10eb-47fd-936c-97e3aaaa3768"> + <interface> + <inputVars> + <variable name="Data"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </inputVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Buffer.Append := TAG_CLOSE; +Buffer.Append := Data; +xTagOpen := FALSE;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="NextTag" ObjectId="d039b781-905d-4b69-b5aa-bb0323e598de"> + <interface> + <returnType> + <derived name="T_MaxString" /> + </returnType> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">iSelectStart := Buffer.Find(sSearchString := TAG_OPEN, udiStartPos := udiSearchPos); +iSelectEnd := Buffer.Find(sSearchString := TAG_CLOSE, udiStartPos := iSelectStart); +iSelectStartPara := Buffer.Find(sSearchString := SPACE, udiStartPos := iSelectStart); +iSelectTagClose := Buffer.Find(sSearchString := FORWARD_SLASH, udiStartPos := iSelectStart); +IF iSelectStart < Buffer.Length AND iSelectEnd < Buffer.Length THEN + udiSearchPos := iSelectEnd; + sTag := Buffer.Copy( udiStart:= iSelectStart + 1, udiEnd:= iSelectEnd); + IF iSelectEnd < iSelectStartPara THEN + NextTag := Buffer.Copy( udiStart:= iSelectStart + 1, udiEnd:= iSelectEnd); + ELSE + NextTag := Buffer.Copy( udiStart:= iSelectStart + 1, udiEnd:= iSelectStartPara); + END_IF; + IF iSelectTagClose = iSelectStart + 1 THEN + iSelect := TagListSeek.FindBack(sSearchString := FORWARD_SLASH); + TagListSeek.CutOff(udiStartPos:= iSelect); + ELSIF iSelectTagClose > iSelectStart AND iSelectTagClose < iSelectEnd THEN + TagListSeek.Append := FORWARD_SLASH; + TagListSeek.Append := NextTag; + iSelect := TagListSeek.FindBack(sSearchString := FORWARD_SLASH); + TagListSeek.CutOff(udiStartPos:= iSelect); + ELSE + TagListSeek.Append := FORWARD_SLASH; + TagListSeek.Append := NextTag; + END_IF; +ELSE + udiSearchPos := Buffer.Length; + NextTag := ''; +END_IF;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="ToStartBuffer" ObjectId="cb065068-a6c8-48d5-8c1d-535a21365348"> + <interface> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Jump to the beginning of the XML data + XML.ToStartBuffer(); +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">udiSearchPos := 0; +TagListSeek.Length := 0; +sTagsSeek := ''; +sTag := '';</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="WriteDocumentHeader" ObjectId="14bf2549-9e7d-451f-8ab5-fe662eb30712"> + <interface> + <inputVars> + <variable name="Header"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </inputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> + Add your own preffered fileheader like: + XML: <?xml version="1.0" encoding="UTF-8"?> + + XML.WriteDocumentHeader('<?xml version="1.0" encoding="UTF-8"?>'); +</xhtml> + </documentation> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">//Buffer.Prepend := Concat(Header, CR_LF); +Buffer.Prepend := Header;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="NextParameter" ObjectId="4394d0a2-f7bc-4847-9625-00022c462a79"> + <interface> + <returnType> + <derived name="T_MaxString" /> + </returnType> + <outputVars> + <variable name="Parameter"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </outputVars> + <localVars> + <variable name="Name"> + <type> + <derived name="T_MaxString" /> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">iSelectEndPara := Buffer.Find(sSearchString := EQUALS, udiStartPos := iSelectStartPara); +IF iSelectStartPara < iSelectEnd AND iSelectEndPara < iSelectEnd THEN + Name := Buffer.Copy( udiStart := iSelectStartPara + 1, udiEnd := iSelectEndPara); + iSelectStartValue := Buffer.Find(sSearchString := QUOTE, udiStartPos := iSelectEndPara); + iSelectEndValue := Buffer.Find(sSearchString := QUOTE, udiStartPos := iSelectStartValue); + Parameter := Buffer.Copy( udiStart := iSelectStartValue + 1, udiEnd := iSelectEndValue); + iSelectStartPara := iSelectEndValue + 1; +ELSE + iSelectEndValue := Buffer.Find(sSearchString := TAG_OPEN, udiStartPos := udiSearchPos); + Name := Buffer.Copy( udiStart := udiSearchPos + 1, udiEnd := iSelectEndValue); +END_IF; +NextParameter := Name;</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/method" handleUnknown="implementation"> + <Method name="SetBuffer" ObjectId="cbfaa6d5-eab9-48d0-a339-a8bf334e344e"> + <interface> + <inputVars> + <variable name="pString"> + <type> + <pointer> + <baseType> + <BYTE /> + </baseType> + </pointer> + </type> + </variable> + <variable name="iSizeOf"> + <type> + <UDINT /> + </type> + </variable> + </inputVars> + </interface> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Buffer.Set(pbyAdr := pString, udiSize := iSizeOf); +TagList.Set(pbyAdr := ADR(sTags), udiSize := SIZEOF(sTags)); +TagListSeek.Set(pbyAdr := ADR(sTagsSeek), udiSize := SIZEOF(sTagsSeek)); +Tag.Set(pbyAdr := ADR(sTag), udiSize := SIZEOF(sTag));</xhtml> + </ST> + </body> + <addData /> + </Method> + </data> + <data name="http://www.3s-software.com/plcopenxml/property" handleUnknown="implementation"> + <Property name="Length" ObjectId="4fdf30b6-5fe7-4452-ad0a-85e866e236d0"> + <interface> + <returnType> + <UDINT /> + </returnType> + </interface> + <GetAccessor> + <interface /> + <body> + <ST> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Length := Buffer.Length;</xhtml> + </ST> + </body> + <addData /> + </GetAccessor> + <addData /> + </Property> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>f48b7de2-5c07-4763-a8be-3d8ab3c1f58c</ObjectId> + </data> + </addData> + </pou> + </pous> + </types> + <instances> + <configurations /> + </instances> + <addData> + <data name="http://www.3s-software.com/plcopenxml/globalvars" handleUnknown="implementation"> + <globalVars name="GVL_System"> + <variable name="_ST_Logger"> + <type> + <derived name="ST_Log" /> + </type> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="hide" Value="" /> + </Attributes> + </data> + </addData> + </variable> + <variable name="_CmpCfLog"> + <type> + <derived name="CmpCfLog" /> + </type> + </variable> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="qualified_only" Value="" /> + <Attribute Name="hide" Value="" /> + </Attributes> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>7e465938-43b3-4ac5-bae5-c19fce2bd2bf</ObjectId> + </data> + </addData> + </globalVars> + </data> + <data name="http://www.3s-software.com/plcopenxml/globalvars" handleUnknown="implementation"> + <globalVars name="GVL_Param_XmlControl" constant="true"> + <variable name="MaxFileSize"> + <type> + <UDINT /> + </type> + <initialValue> + <simpleValue value="32767" /> + </initialValue> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Maximum filesize in bytes (32 kb default)</xhtml> + </documentation> + </variable> + <variable name="FilePath"> + <type> + <derived name="T_MaxString" /> + </type> + <initialValue> + <simpleValue value="'c:/jenkins/workspace/XmlResultTester/testresult.xml'" /> + </initialValue> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Filepath for testresult.xml, e.g.: c:/jenkins/workspace/XmlResultTester/testresult.xml</xhtml> + </documentation> + </variable> + <addData> + <data name="http://www.3s-software.com/plcopenxml/attributes" handleUnknown="implementation"> + <Attributes> + <Attribute Name="parameterlist" Value="" /> + <Attribute Name="qualified_only" Value="" /> + </Attributes> + </data> + <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard"> + <ObjectId>69588962-bd3e-4958-957e-7bfb94609af1</ObjectId> + </data> + </addData> + </globalVars> + </data> + <data name="http://www.3s-software.com/plcopenxml/interface" handleUnknown="implementation"> + <Interface name="I_TestResultFormatter" ObjectId="fa75ee61-43fb-4767-8061-125a3a9e3424"> + <Methods> + <Method name="Format" ObjectId="4eb108d9-22ef-4b8a-ba8b-39eb19e8c6ef"> + <interface> + <inputVars> + <variable name="NumberOfTestSuites"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test suites </xhtml> + </documentation> + </variable> + <variable name="NumberOfTestCases"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test cases (for all test function blocks) </xhtml> + </documentation> + </variable> + <variable name="NumberOfSuccessfulTestCases"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test cases that had all ASSERTS successful </xhtml> + </documentation> + </variable> + <variable name="NumberOfFailedTestCases"> + <type> + <UINT /> + </type> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> The total number of test cases that had at least one ASSERT failed </xhtml> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="Busy"> + <type> + <BOOL /> + </type> + </variable> + </outputVars> + <documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml"> Responsible for formatting the xml file skeleton + <testsuites> => the aggregated result OF all xunit testfiles + <testsuite> => the output from a single TestSuite + <properties> => the defined properties at test execution + <property> => name/value pair for a single property + ... + </properties> + <error></error> => optional information, in place of a test case - normally if the tests in the suite could not be found etc. + <testcase> => the results from executing a test method + <system-out> => data written to System.out during the test run + <system-err> => data written to System.err during the test run + <skipped/> => test was skipped + <failure> => test failed + <error> => test encountered an error + </testcase> + ... + </testsuite> + ... + </testsuites></xhtml> + </documentation> + </interface> + <addData /> + </Method> + </Methods> + <addData /> + </Interface> + </data> + <data name="http://www.3s-software.com/plcopenxml/projectstructure" handleUnknown="discard"> + <ProjectStructure> + <Object Name="prg_Example" ObjectId="917c49f4-3643-42fe-b791-ac2edc0df35b" /> + <Folder Name="CmpLog"> + <Object Name="FB_XmlFileFormatter" ObjectId="6597c0b3-0890-4d5d-8d3a-2d0d0b2355db"> + <Object Name="Format" ObjectId="b6b6021c-eac1-4ed2-91cd-9954fbe29c28" /> + <Object Name="FB_Init" ObjectId="0f23c47b-7245-415e-b489-0ae429217263" /> + <Object Name="OpenSaveAndClose" ObjectId="bdefa095-3448-4b85-b486-ff4d5205677b" /> + </Object> + <Object Name="I_TestResultFormatter" ObjectId="fa75ee61-43fb-4767-8061-125a3a9e3424"> + <Object Name="Format" ObjectId="4eb108d9-22ef-4b8a-ba8b-39eb19e8c6ef" /> + </Object> + <Object Name="GVL_System" ObjectId="7e465938-43b3-4ac5-bae5-c19fce2bd2bf" /> + </Folder> + <Object Name="E_XmlError" ObjectId="05a4fdda-1086-47b5-ad10-7c2bac568355" /> + <Folder Name="FileControl"> + <Documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Imported from XML parsing and composing library (xml-pac) 0.3.1.0</xhtml> + </Documentation> + <Object Name="FB_FileControl" ObjectId="c9bec8fc-2de3-45f4-b839-e6c4276a6b5a"> + <Object Name="Close" ObjectId="519e9011-283c-40b1-afd4-31686c5b81fe" /> + <Object Name="Open" ObjectId="1873bb2c-c6a3-4681-8948-02aa2bad0a9b" /> + <Object Name="Read" ObjectId="3984ae50-1cdb-4045-af99-0bb56917afb2" /> + <Object Name="Save" ObjectId="c4146a99-50c6-4ce0-88ab-794dbfb1af62" /> + </Object> + </Folder> + <Object Name="GVL_Param_XmlControl" ObjectId="69588962-bd3e-4958-957e-7bfb94609af1" /> + <Folder Name="StreamBuffer"> + <Object Name="FB_StreamBuffer" ObjectId="fbccbed5-94ee-455b-a9d5-e8b750ed732e"> + <Object Name="Append" ObjectId="ddd7c0b6-46f9-4fa9-946e-0da608268245" /> + <Object Name="BufferSize" ObjectId="879a667c-416e-4879-91ff-6641233ded93" /> + <Object Name="Clear" ObjectId="5f0bbce2-2600-4a2e-8c6f-4b957ad03395" /> + <Object Name="Copy" ObjectId="b796dd60-63f5-4b75-acc5-8fa40e24be46" /> + <Object Name="CutOff" ObjectId="8914e4f8-8b6c-48c3-ba1f-e0642038624a" /> + <Object Name="Find" ObjectId="7e38490a-9555-451d-957e-fef284a567e3" /> + <Object Name="FindBack" ObjectId="7d08b204-2078-4fde-81eb-e04d71986196" /> + <Object Name="Length" ObjectId="80c3b0fb-2bdc-4829-89c6-017e171b31eb" /> + <Object Name="Prepend" ObjectId="c4fdd2db-7736-4bc5-a06f-ba3a29618794" /> + <Object Name="Set" ObjectId="59092938-ca22-4896-8f54-1c854a0bd883" /> + </Object> + </Folder> + <Object Name="T_MaxString" ObjectId="a429e267-db3b-4872-871e-1ca509b971e2" /> + <Folder Name="XmlControl"> + <Documentation> + <xhtml xmlns="http://www.w3.org/1999/xhtml">Imported from XML parsing and composing library (xml-pac) 0.3.1.0</xhtml> + </Documentation> + <Object Name="FB_XmlControl" ObjectId="f48b7de2-5c07-4763-a8be-3d8ab3c1f58c"> + <Object Name="NewTag" ObjectId="c44bdbda-725a-4943-a5cc-fa5ea9485541" /> + <Object Name="ClearBuffer" ObjectId="651b4460-232e-47e8-95ba-ecea1541fbb9" /> + <Object Name="CloseTag" ObjectId="eedd2aac-2425-4325-8128-bfe1e984f3f7" /> + <Object Name="Length" ObjectId="4fdf30b6-5fe7-4452-ad0a-85e866e236d0" /> + <Object Name="NewComment" ObjectId="0f41fa45-b92e-4e7e-b2b3-ecb5d5918326" /> + <Object Name="NewParameter" ObjectId="60c10606-ff09-4f9b-a3dd-0b54d0f565c7" /> + <Object Name="NewTagData" ObjectId="e4679d3f-10eb-47fd-936c-97e3aaaa3768" /> + <Object Name="NextTag" ObjectId="d039b781-905d-4b69-b5aa-bb0323e598de" /> + <Object Name="ToStartBuffer" ObjectId="cb065068-a6c8-48d5-8c1d-535a21365348" /> + <Object Name="WriteDocumentHeader" ObjectId="14bf2549-9e7d-451f-8ab5-fe662eb30712" /> + <Object Name="NextParameter" ObjectId="4394d0a2-f7bc-4847-9625-00022c462a79" /> + <Object Name="SetBuffer" ObjectId="cbfaa6d5-eab9-48d0-a339-a8bf334e344e" /> + </Object> + </Folder> + </ProjectStructure> + </data> + </addData> +</project> \ No newline at end of file