Facility Control

 View Only
  • 1.  New to parsing XML

    Posted 12-23-2019 20:38

    My eventual end goal, which I still have 6 months to get working, is to create a dashboard interface to track stats of high school football. I know there are programs that will already do this, but I have been told those aren't options...so we go to the old school method of "let's see what we can do ourselves!"

    So I'm madly trying to teach myself javascript to be able to do this, and I've watched and downloaded the XML example file from "Dashboard U," but I'm still lost. So far I just can't wrap my head around for loops yet...and I'm not even sure I need them if I'm not planning on displaying a whole team in an array at the same time?  I just want to type a player number, press a button for "Pass Complete" and then I think I understand enough Javascript so far to do some math on those variables...I think!

    (I wish I could read and write directly from Excel through Dashboard for ease of "import and export" before and after a game, but I understand that's not possible in Dashboard, only reading in XPression.)

    If someone could help me answer the following two questions, with a "real world" example relevant to me, I think I could figure out (most of) the rest of the project, or at least the main points.
    1. How could I, for example, read the name of player number 1 and assign that to a label parameter?
    2. How could I add a completion to player 2?

    Just looking to do simple 1-at-a-time parameters, not making a whole array of each player.

    Here's the sample XML:
    <HomeTeam>
    <Player num="1" name="Bill" POS="QB" HT="5'12&qout;" WT="115" Grade="SR" PassATT="10" PassCOMP="9" PassYDS="150" PassREC="0" PassINT="1" PassTD="3" PassFUM="0" />
    <Player num="2" name="Johnny" POS="RB" HT="6'6&qout;" WT="107" Grade="JR" PassATT="0" PassCOMP="0" PassYDS="0" PassREC="0" PassINT="0" PassTD="0" PassFUM="0" />
    <Player num="3" name="Eustace" POS="K" HT="5'1&qout;" WT="245" Grade="FR" PassATT="0" PassCOMP="0" PassYDS="0" PassREC="0" PassINT="0" PassTD="0" PassFUM="0" />
    </HomeTeam>

    Plan C is to just use Access, but I like the idea of using Dashboard which can just be installed on anyhting and run from anywhere!

    Thanks!
    -Dan



  • 2.  RE: New to parsing XML

    Posted 12-30-2019 23:34

    Hi Dan

    I'm wondering if you might find it easier to use a CSV file which could be edited in Excel and parsed fairly easily via ogScript. For now, you're in the XML world so we'll start with that. You may find XPath to be your best way to look things up:

    var XMLDoc = ogscript.parseXML('path_to_xml.xml');

    var node = ogscript.runXPath("/HomeTeam/Player[@num='1']", XMLDoc).item(0);

    params.setValue('label_param_name', 0, node.getAttribute('name'));

     

    As for setting the value, you'll want to modify your attribute and then us ogscript.writeToFile('path_to_xml.xml', XMLDoc);

    var XMLDoc = ogscript.parseXML('path_to_xml.xml'); //JUST DO THIS ONCE IN AN API BLOCK AND USE THE OBJECT EVERYWHERE

    var node = ogscript.runXPath("/HomeTeam/Player[@num='2']", XMLDoc).item(0);

    var existingComp = parseInt(node.getAttribute('PassCOMP'));

    node.setAttribute('PassCOMP', existingComp + 1);

    ogscript.writeToFile('path_to_xml.xml', XMLDoc);

     

    Cheers

    James


    #DashBoard


  • 3.  RE: New to parsing XML

    Posted 12-30-2019 23:48

    James, you're not wrong, CSV would be perfect! I hadn't even thought of that as an option. I assume XPression can read a CSV just as easily as anything else?  Because I haven't yet managed to get a working XML export from Excel, and if I can use a CSV, then the lay-people that will be running this (of which I'm still one, really) can still do normal edits and copy/pasta in Excel without having to export and such!

    Though that code looks a lot simpler than I thought it would be! Could I trouble you to give me an example of the same thing for a CSV as well?  It's SO early in the project, that I don't really have a player database (except last season's Excel version) so right at this moment, I can go in whatever direction is the easiest!

     

    Thanks for the response!


    #DashBoard


  • 4.  RE: New to parsing XML

    Posted 01-06-2020 21:50

    Your post is like déjà vu of my situation a few years back, so I felt I really should reach out to help you along the awesome but challenging journey that lies ahead of you. Here is a link to a DB we made that has the functionality I think that you are describing, and you’re welcome to use this file and repurpose it. It is kind of a combination of different approaches. There is a tab for Basketball Stats, which is a self-contained stats system within the DB. There is also a tab Basketball Excel Stats, which imports stats from the accompanying Excel .xml file, BUT you’ll need to reconnect it in the code, which I believe is in the “Get Stats” button on that tab. All this should help, BUT I’m not going to kid you. Repurposing this DB will be quite a headache for a beginner. I suggest that you start from scratch, clearly write out what you want to do and how it will look(and be ready to revise this as you learn more), while you teach yourself some JavaScript from https://www.codecademy.com/ or some other online resource. You don’t need to go too deep into JavaScript really for what you are doing. The Intro To JavaScript class on codecademy should be fine, and if you find the subject of Classes confusing, then I’d just stop there and copy code from other projects and reporpose it for yourself. Then focus more on learning how to format your Dashboard, bc that is a whole different beast you’ll have to tackle. A key to success for me was using the Add button in the Tasks section of the Edit Component Window(You can find this by double clicking a component such as a button when you are in Edit Mode.) Then the Add Tasks window will pop-up. Next change from Visual to OgScript and make sure the Script Pallet is checked. Then you can refence a library of JavaScript and ogScripts to do some stuff you’ll need to do. Most importantly, use the ogScript function:

    ogscript.debug("The value of variableHere is: " + variableHere);

     

    this will essentially output: The value of variableHere is: 20. (assuming the value of the variable is 20). You can see all this output by selecting View > Open Debug Information, and the output should be appear in the panel on the right side of your screen.

    Good luck, and feel free to post more questions if you get stuck. This community is very helpful as long as you are patient.


    #DashBoard


  • 5.  RE: New to parsing XML

    Posted 01-07-2020 14:13

    Thanks for offering-up that great advice, Roger.

    Dan, CSV parsing is not built directly into DashBoard but is a fairly straight-forward function to write in JavaScript. I'm including a demo panel designed to read a 17-column CSV file and load them into parameters (one parameter for each column).

    The function "processCSV" would be reusable wherever you'd like (it's in an <api/> tag). You just need to name your parameters with a common prefix and a numeric suffix (e.g. "col.0", "col.1", "col.2", ...)

    function processCSV(fileContent, oidPrefix)
    {
    if (fileContent == null)
    {
    ogscript.debug("CAN'T LOAD FILE");
    return;
    }

    var rows = fileContent.split('\n');
    var dataByColumn = []; //It is more efficient if we only call "SET" on the parameters once

    for (var r = 0; r < rows.length; r++)
    {
    var cols = rows[r].trim().split(',');
    for (var c = 0; c < cols.length; c++)
    {
    if (c >= dataByColumn.length)
    {
    dataByColumn.push([]); //Add a new column if it wasn't already created
    }
    dataByColumn[c][r] = cols[c].trim(); //Push the cell's value into the array of column data at row "r"
    }
    }


    //Now that we have collected all of the data for each column into an array, we can call setAllValues for the array parameter
    for (var c = 0; c < dataByColumn.length; c++)
    {
    params.setAllValues(oidPrefix + '.' + c, dataByColumn[c]); //Set all of the values in the column
    }
    }

    Sample Panel:

    <abs contexttype="opengear" style="">
    <meta>
    <params>
    <param access="1" maxlength="0" name="Column 1" oid="cols.1" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 2" oid="cols.2" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 3" oid="cols.3" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 4" oid="cols.4" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 5" oid="cols.5" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 6" oid="cols.6" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 7" oid="cols.7" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 8" oid="cols.8" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 9" oid="cols.9" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 10" oid="cols.10" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 11" oid="cols.11" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 12" oid="cols.12" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 13" oid="cols.13" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 14" oid="cols.14" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 15" oid="cols.15" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 16" oid="cols.16" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" maxlength="0" name="Column 0" oid="cols.0" precision="0" stateless="true" type="STRING_ARRAY" value="" widget="label">
    <value>
    </value>
    </param>
    <param access="1" constrainttype="STRING_CHOICE" name="table" oid="table" precision="0" type="INT16" value="-1" widget="table">
    <constraint>cols.0</constraint>
    <constraint>cols.1</constraint>
    <constraint>cols.2</constraint>
    <constraint>cols.3</constraint>
    <constraint>cols.4</constraint>
    <constraint>cols.5</constraint>
    <constraint>cols.6</constraint>
    <constraint>cols.7</constraint>
    <constraint>cols.8</constraint>
    <constraint>cols.9</constraint>
    <constraint>cols.10</constraint>
    <constraint>cols.11</constraint>
    <constraint>cols.12</constraint>
    <constraint>cols.13</constraint>
    <constraint>cols.14</constraint>
    <constraint>cols.15</constraint>
    <constraint>cols.16</constraint>
    </param>
    </params>
    <api immediate="true">function processCSV(fileContent, oidPrefix)
    {
    if (fileContent == null)
    {
    ogscript.debug("CAN'T LOAD FILE");
    return;
    }

    var rows = fileContent.split('\n');
    var dataByColumn = []; //It is more efficient if we only call "SET" on the parameters once

    for (var r = 0; r &lt; rows.length; r++)
    {
    var cols = rows[r].trim().split(',');
    for (var c = 0; c &lt; cols.length; c++)
    {
    if (c &gt;= dataByColumn.length)
    {
    dataByColumn.push([]); //Add a new column if it wasn't already created
    }
    dataByColumn[c][r] = cols[c].trim(); //Push the cell's value into the array of column data at row "r"
    }
    }


    //Now that we have collected all of the data for each column into an array, we can call setAllValues for the array parameter
    for (var c = 0; c &lt; dataByColumn.length; c++)
    {
    params.setAllValues(oidPrefix + '.' + c, dataByColumn[c]); //Set all of the values in the column
    }
    }</api>
    </meta>
    <param bottom="5" expand="true" left="6" oid="table" right="8" showlabel="false" top="104"/>
    <button buttontype="push" height="84" left="5" name="Read" top="7" width="186">
    <task tasktype="ogscript">ogscript.asyncPost('CSV Reader Data.csv', null, function (result)
    {
    processCSV(result, 'cols');

    });

    </task>
    </button>
    </abs>

    Cheers

    James


    #DashBoard


  • 6.  RE: New to parsing XML

    Posted 01-07-2020 22:49

    Hi James!
    I'm back to trying XML (sorry...), but I'm having some trouble getting it to work out.

    Here's my XML again:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

    <teamHome xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

        <player>

            <num>1</num>

            <name>John Doe</name>

            <pos>QB</pos>

            <ht>5'10"</ht>

            <wt>165</wt>

            <grade>JR</grade>

        </player>

        <player>

            <num>2</num>

            <name>James Doe</name>

            <pos>RB/LB</pos>

            <ht>5'10"</ht>

            <wt>150</wt>

            <grade>SR</grade>

        </player>

        <player>

            <num>3</num>

            <name>Bill Buckner</name>

            <pos>CB</pos>

            <ht>5'8"</ht>

            <wt>145</wt>

            <grade>SR</grade>

        </player>

        <player>

            <num>4</num>

            <name>Jason Statham</name>

            <pos>LB/RB</pos>

            <ht>5'11"</ht>

            <wt>185</wt>

            <grade>SR</grade>

        </player>

    </teamHome>

    And here's my (incredibly complex and beautiful) panel:

    <?xml version="1.0" encoding="UTF-8"?><abs contexttype="opengear" gridsize="20" id="_top" keepalive="false" style="">

       <meta>

          <params>

             <param access="1" maxlength="0" name="String1" oid="string1" type="STRING" value="One" widget="text"/>

             <param access="1" maxlength="0" name="pathPlayersHome" oid="pathPlayersHome" type="STRING" value="D:\Documents\GoogleDrive\TruckGraphics\Databases\01 GameDb\PlayersHome.xml" widget="default"/>

          </params>

       </meta>

       <abs bottom="20" id="canvasMain" left="0" right="0" scroll="true" top="0">

          <param expand="true" height="60" left="20" oid="string1" showlabel="false" top="140" width="420"/>

          

          

          

          <button buttontype="push" height="80" id="buttRead1" left="20" name="Read 1" top="40" width="200">

             <task tasktype="ogscript">var XMLDoc = ogscript.parseXML(var [paramValue] = params.getValue('pathPlayersHome', 0);

    var node = ogscript.runXPath("/teamHome/player[@num='1']", XMLDoc).item(0);

    params.setValue(params.setValue('string1', 0, node.getAttribute('name'));</task>

          </button>

          <button buttontype="push" height="80" id="buttWrite1" left="240" name="Write 1" top="40" width="200"/>

          

       <table height="60" left="20" oid="pathPlayersHome" top="220" width="980">

             <tr>

                <label anchor="east" fill="none" insets="0,0,0,5" name="pathPlayersHome" weightx="0.0"/>

                <param anchor="west" expand="true" fill="both" oid="pathPlayersHome" showlabel="false" weightx="1.0" weighty="1.0"/>

             </tr>

          </table>

       </abs>

    </abs>

    There's an argument that I should I have started with this... :)

    Does anyone see what's wrong with it?

    Can someone explain the:  [@num='1']", XMLDoc).item(0);
    I think I understand that it's getting all the children of "player" that "num 1," (I think), but what is the item(0) method?


    #DashBoard


  • 7.  RE: New to parsing XML

    Posted 01-08-2020 16:48

    this panel looks pretty basic, are you sure this is the correct code?


    #DashBoard


  • 8.  RE: New to parsing XML

    Posted 01-08-2020 17:24

    Yeah, I just started a new panel with a "read" button, a "write" button and a string that I could read and write from. Now I'm just trying to get James' code from his original response to work and grow it from there, instead of starting for a complex, fully functioning GUI and trying to test things while not breaking all of that.


    #DashBoard


  • 9.  RE: New to parsing XML

    Posted 01-08-2020 18:30

    well, i couldn't make sense of it, so i modified it a bit.
    it's kind of rough, but with this you can search for tags in the xml and it takes the text content of those tags and puts them in a string.
    i commented it heavily, so you can reuse it for your own purposes.
    i didn't attempt the write button, bc i still cant understand what you want to write.
    good luck.


    <abs contexttype="opengear">
    <meta>
    <params>
    <param access="1" constrainttype="INT_NULL" name="elementsFound" oid="elementsFound" precision="0" type="INT16" value="4" widget="default"/>
    <param access="1" maxlength="0" name="finalReturnedXML" oid="finalReturnedXML" precision="0" type="STRING_ARRAY" value="1;2;3;4" widget="default">
    <value>1</value>
    <value>2</value>
    <value>3</value>
    <value>4</value>
    </param>
    <param access="1" maxlength="0" name="returnedString" oid="returnedString" type="STRING" value=" 1, 2, 3, 4, " widget="text"/>
    <param access="1" maxlength="0" name="searchString" oid="searchString" type="STRING" value="num" widget="text"/>
    <param access="1" maxlength="0" name="xmlPath" oid="xmlPath" type="STRING" value="C:/DashBoard/Practice_Panel_01/BaseballDan/baseballDan.xml" widget="default"/>
    </params>
    </meta>
    <abs bottom="20" id="canvasMain" left="0" right="0" scroll="true" top="0">
    <param expand="true" height="60" left="128" oid="string1" showlabel="false" top="387" width="420"/>
    <button buttontype="push" height="80" id="buttRead1" left="20" name="Read 1" top="40" width="200">
    <task tasktype="ogscript">var xmlPathVar = params.getValue('xmlPath', 0); //this variable holds the user defined path
    var extPath = "file:///"; //this defines that the string is a FILE, not a web address
    xmlPath = extPath + xmlPathVar; //this appends the two above variables

    var testXML = ogscript.parseXML(xmlPath); //this variable stores all the parsed xml in Dashboard

    // check parse worked
    if (testXML == null) {
    // if parse failed debug msg
    ogscript.debug('Failed to read file');

    } else {
    // if parse worked
    ogscript.debug('Parsing XML');

    var searchTag = params.getValue('searchString', 0); //this sets the search string


    var dataTags = testXML.getElementsByTagName(searchTag); // seperates the testXML data by the searchTag(s) in an array called dataTags.

    if (dataTags.length == 0)
    {
    // if parse failed debug msg
    ogscript.debug('Failed to find that tag');
    } else {

    ogscript.debug("items found: " + dataTags.length); // degub msg dataTags array length

    params.setValue('elementsFound', 0, dataTags.length); // set param, elementsFound, to dataTags length

    var myString = " "; //create an empty string to later add our results to

    // loop through dataTags array and return only text content in new array,
    for (xmlData = 0; xmlData &lt; dataTags.length; xmlData++) {

    var node = dataTags.item(xmlData); //making variable of the current node for this loop through the dataTags array
    var xmlDataTagsText = node.getTextContent(); // making variable for the Text Content in this node
    ogscript.debug("No. " + xmlData + " contains: " + xmlDataTagsText); // debug msg for Text value returned
    params.setValue('finalReturnedXML', xmlData, xmlDataTagsText); // set a finalReturnedXML param value for text returned in dataTag
    myString += xmlDataTagsText + ', '; //appending current node's text content to our outputstring
    }


    params.setValue('returnedString', 0, myString); //output string to output textbox


    }

     

     

    }</task>
    </button>
    <button buttontype="push" height="80" id="buttWrite1" left="240" name="Write 1" top="40" width="200"/>
    <table height="60" left="20" oid="pathPlayersHome" top="220" width="840">
    <tr>
    <label anchor="east" fill="none" insets="0,0,0,5" name="xml path" weightx="0.0"/>
    <param anchor="west" expand="true" fill="both" oid="xmlPath" showlabel="false" weightx="1.0" weighty="1.0"/>
    </tr>
    </table>
    <param expand="true" height="60" left="128" oid="string1" showlabel="false" top="304" width="420"/>
    <param expand="true" height="74" left="133" oid="searchString" top="298" width="384"/>
    <param expand="true" height="68" left="138" oid="returnedString" top="399" width="380"/>
    </abs>

    <label anchor="east" fill="none" height="18" insets="0,0,0,5" left="27" name="search tag" top="329" weightx="0.0" width="103"/>
    <label anchor="east" fill="none" height="18" insets="0,0,0,5" left="28" name="results" top="428" weightx="0.0" width="103"/>
    </abs>

     


    #DashBoard


  • 10.  RE: New to parsing XML

    Posted 01-08-2020 20:03

    <x-zendesk-user data-user-name="Dan Silvia">372671799091</x-zendesk-user> The [@num='1']", XMLDoc).item(0); part is looking for the nodes where the "num" attribute is equal to "1".  The runXPath command returns an object called  NodeList (https://docs.oracle.com/javase/8/docs/api/org/w3c/dom/NodeList.html) and you will need to get the XML element out of it. To get a Node out of the NodeList, you use the "item" method and pass it the element index (in this case, we want the first node returned so we pass it element 0).

     


    #DashBoard