VoxCommando Forum

Help and Support (Using VoxCommando) => VoxCommando Basics and Core Features => Topic started by: rtenklooster on November 27, 2014, 01:00:41 PM

Title: Function scrape.XML look for multiple nodes.
Post by: rtenklooster on November 27, 2014, 01:00:41 PM
Hi,
As found in the documentation, i want to scrape an xml url, and return the values for two nodes.
the xml is:
<xml>
<otGwstate>
<flame>0</flame>
<dhwmode>1</dhwmode>
<chmode>0</chmode>
<dhwenable>1</dhwenable>
<diag>0</diag>
<fault>0</fault>
<outside>???</outside>
<temperature>20.40</temperature>
<setpoint>16.00</setpoint>
<modulation>0.00</modulation>
<boilertemp>54.12</boilertemp>
<returntemp>49.75</returntemp>
<controlsp>10.00</controlsp>
<dhwsetpoint>60.00</dhwsetpoint>
<chwsetpoint>75.00</chwsetpoint>
<overridetemp>0.00</overridetemp>
<b>0</b>
<dhwtemperature>39.50</dhwtemperature>
<c>0</c>
<d>0</d>
<e>0</e>
<maxRelModLevel>0.00</maxRelModLevel>
<f>0</f>
<g>0</g>
<h>1.36</h>
<pressure>0</pressure>
<i>0</i>
<j>0</j>
<k>0</k>
<l>0</l>
<m>0</m>
<n>0</n>
<date>20141126</date>
<time>23:38:30</time>
</otGwstate>
</xml>


Let's say i want to get flame and setpoint. What i did, was fill in: flame, setpoint.
{Match.1} and {Match.2}remain empty. If i just fill in flame, or setpoint, it retreives that value like it's supposed to do.

Am i misunderstanding the manual? Or do i have to use regular expressions for this?
I tried to fill in the nodesname in different ways, sepeated bij comma, in brackets etc. I have no idea how to do this. Help would be appreciated.
Title: Re: Function scrape.XML look for multiple nodes.
Post by: nime5ter on November 27, 2014, 01:13:46 PM
Yes, the Scrape.XML is not particularly sophisticated. To my knowledge you can only choose one node label at a time. It is still usable for what you have in mind, but I typically use Results.RegEx instead.

Here are 2 possibilities for the scenario you mention. One command uses Scrape.XML and stores each value as a variable, the other uses Results.RegExSingle:

<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.1.2.1-->
<commandGroup open="True" name="scraping xml" enabled="True" prefix="" priority="0" requiredProcess="" description="">
  <command id="295" name="using scrape.xml" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
    <action>
      <cmdType>Scrape.XML</cmdType>
      <params>
        <param>YOUR URL</param>
        <param>flame</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <action>
      <cmdType>Results.SetVar</cmdType>
      <params>
        <param>flame</param>
        <param>{Match.1}</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <action>
      <cmdType>Scrape.XML</cmdType>
      <params>
        <param>YOUR URL</param>
        <param>setpoint</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <action>
      <cmdType>Results.SetVar</cmdType>
      <params>
        <param>setpoint</param>
        <param>{Match.1}</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <action>
      <cmdType>OSD.ShowText</cmdType>
      <params>
        <param>Flame: {var.flame}{CR}Setpoint: {var.setpoint}</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <phrase>scrape nodes</phrase>
  </command>
  <command id="296" name="using results.regex" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
    <action>
      <cmdType>Scrape</cmdType>
      <params>
        <param>YOUR URL</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <action>
      <cmdType>Results.RegExSingle</cmdType>
      <params>
        <param>&lt;flame&gt;(.*?)&lt;.*?&lt;setpoint&gt;(.*?)&lt;</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <action>
      <cmdType>OSD.ShowText</cmdType>
      <params>
        <param>Flame: {Match.1.1}{cr}Setpoint: {Match.1.2}</param>
      </params>
      <cmdRepeat>1</cmdRepeat>
    </action>
    <phrase>use regular expressions</phrase>
  </command>
</commandGroup>
Title: Re: Function scrape.XML look for multiple nodes.
Post by: nime5ter on November 27, 2014, 03:22:48 PM
You can also capture all nodes nicely using just Results.Regex.

Here I display the first 10 nodes. (The variable {#M} can be used instead if you want to use all matches.)

<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.1.2.1-->
<command id="314" name="version 2 - using results.regex" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
  <action>
    <cmdType>Scrape</cmdType>
    <params>
      <param>YOUR URL</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>RegExTool.Open</cmdType>
    <params>
      <param>True</param>
    </params>
    <cmdRepeat>0</cmdRepeat>
  </action>
  <action>
    <cmdType>Results.RegEx</cmdType>
    <params>
      <param>&lt;(.*?)&gt;(.*?)&lt;</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.ShowText</cmdType>
    <params>
      <param>Node /  Value</param>
      <param>15000</param>
    </params>
    <cmdRepeat>1</cmdRepeat>
  </action>
  <action>
    <cmdType>OSD.AddText</cmdType>
    <params>
      <param>{Match.{i}.1}: {Match.{i}.2}</param>
    </params>
    <cmdRepeat>10</cmdRepeat>
  </action>
  <phrase>capture all nodes</phrase>
</command>


This is very similar to the example James demonstrates in the 1st Regex Tool tutorial: https://www.youtube.com/watch?v=G_tEroy_9Mw&feature=youtu.be&t=2m10s
Title: Re: Function scrape.XML look for multiple nodes.
Post by: rtenklooster on November 28, 2014, 04:21:37 PM
Great! Thanks for supplying such good solutions! I used the regEx one :-)

It's just the manual is talking about matcheS so i supposed you can use the scrapeXML for multiple nodes.
No problem, glad we have the forum!
Title: Re: Function scrape.XML look for multiple nodes.
Post by: nime5ter on November 28, 2014, 04:36:45 PM
I see what you mean.

The documentation is referring to the fact that there can be multiple matches of the same element node within an XML document.

To steal an example (ref: http://www.w3schools.com/dom/dom_nodes.asp):
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="children">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title lang="en">XQuery Kick Start</title>
    <author>James McGovern</author>
    <author>Per Bothner</author>
    <author>Kurt Cagle</author>
    <author>James Linn</author>
    <author>Vaidyanathan Nagarajan</author>
    <year>2003</year>
    <price>49.99</price>
  </book>
  <book category="web" cover="paperback">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>


If you scrape.xml the above for the element node "title", VC will find four matches:

{Match.1} = Everyday Italian
{Match.2} = Harry Potter
{Match.3} = XQuery Kick Start
{Match.4} = Learning XML

In your particular xml file, the same element node may appear only once, but that's not always the case. Hence the plural matcheS. :)
Title: Re: Function scrape.XML look for multiple nodes.
Post by: jitterjames on November 28, 2014, 07:00:32 PM
XML is a many tentacled creature!
Title: Re: Function scrape.XML look for multiple nodes.
Post by: rtenklooster on November 29, 2014, 11:00:41 AM
Quote from: nime5ter on November 28, 2014, 04:36:45 PM
I see what you mean.

The documentation is referring to the fact that there can be multiple matches of the same element node within an XML document.

To steal an example (ref: http://www.w3schools.com/dom/dom_nodes.asp):

...

Ah, now i get it :-) Thanks for making this clear to me!