content from XML

So i’m trying to get specific values from a xml file but after days of searching I’m none the wiser

This is the source XML

[code]

UPS Status

UPS Status

      <h2 class="expandable ">- System Status</h2>
      <div class="label-value-group ui-corner-all">
    
    
    <div class="label-value-pair">
      <label>Device Status</label>
      
        <div id="value_DeviceStatus" class="value">On line (Green Mode)</div>
        
    </div>
    
    
    
    <div class="label-value-pair">
      <label>UPS Load</label>
      
        <div id="value_RealPowerPct" class="value">20.8</div>
        <div class="unit">%</div>
    </div>
    
    
    
    <div class="label-value-pair">
      <label>Runtime Remaining</label>
      
        <div id="value_RuntimeRemaining" class="value">49</div>
        <div class="unit">Minutes</div>
    </div>
    
    </div>

</div>
There is a problem retrieving information for this dialog. Please close this dialog and try again. Close
[/code]

I first thought LXP and xpatch would be the cleanest way to do it so I stole this code

[code]local socket = require(“socket”)
local ltn12 = require(‘ltn12’)
local https = require(“ssl.https”)
local lom = require’lxp.lom’
local xpath = require’xpath’

function https.get(u)
local response_body = { }
local rBody, code, response_headers, rStatus = https.request{
url = u,
method = “GET”,
verify = “none”,
mode = “client”,
options = “all”,
protocol = “sslv3”,
headers = {
[“Accept”] = “text/html”,
[“Accept-Encoding”] = “sdch”,
},
sink = ltn12.sink.table(response_body),
}
return table.concat(response_body), rBody, code, response_headers, rStatus
end

local xml_tree = lom.parse(https.get((‘https://192.168.148.3:6547/quickstatus’)))
print(xml_tree)
[/code]

The output was blank and this is the furthest I’ve have gotten without any errors :-[

Then I thought regex could solve it but this code won’t work neither probably because of the " symbols
I’m trying to get this

<div id="value_DeviceStatus" class="value">On line (Green Mode)</div>

[code]
local socket = require(“socket”)
local ltn12 = require(‘ltn12’)
local https = require(“ssl.https”)
local lom = require’lxp.lom’
local xpath = require’xpath’

function https.get(u)
local response_body = { }
local rBody, code, response_headers, rStatus = https.request{
url = u,
method = “GET”,
verify = “none”,
mode = “client”,
options = “all”,
protocol = “sslv3”,
headers = {
[“Accept”] = “text/html”,
[“Accept-Encoding”] = “sdch”,
},
sink = ltn12.sink.table(response_body),
}
return table.concat(response_body), rBody, code, response_headers, rStatus
end

local xml_tree = (https.get((‘https://192.168.148.3:6547/quickstatus’)))
local DeviceStatus = xml_tree: match “

([^<]*)

print(DeviceStatus)[/code]

returns a “attempt to call global ‘value_DeviceStatus’ (a nil value)”

The XML file is not that big and i’ve read that regex is faster then LXP. So what is the best approach in my case and what I’m I doing wrong?

My reading material for anyone who’s on the same path:
[url=http://luaxpath.luaforge.net/manual.html]http://luaxpath.luaforge.net/manual.html[/url] LUA XPath
[url=http://forum.micasaverde.com/index.php?topic=12408.15]http://forum.micasaverde.com/index.php?topic=12408.15[/url] user: Hek, wrote a nice script that uses LXP and Xpath
[url=http://forum.micasaverde.com/index.php/topic,15176.0.html]http://forum.micasaverde.com/index.php/topic,15176.0.html[/url] user: mda, wrote a script that uses regex

Belkin WeMo plugin and the weatherparsing script also uses LXP but that script was way to complex for me to understand

At least one of your problems is this line

local DeviceStatus = xml_tree: match "<div id="value_DeviceStatus" class="value">([^<]*)</div>"

You could fix it like this

local DeviceStatus = xml_tree: match '<div id="value_DeviceStatus" class="value">([^<]*)</div>'

…although there are others ways too.

Heres a simple solution for you…


function getParams(html)
  local params = {}
  html = html:gsub("\r",""):gsub("\n",""):gsub('<head>(.+)</head>',''):gsub('(.+)<div id="mainbox">','')
  for vID,vValue in html:gmatch('<div id="(.-)" class="value">(.-)</div>') do
    params[vID] = vValue
  end
  return params
end

This will extract all the parameters on the page into a lua array.

You can then reference the returned values by name…

eg:

local html = https.get('https://192.168.148.3:6547/quickstatus')
local rValues = getParams(html)
local upsStatus = rValues["value_DeviceStatus"]

Basically, the getParams function strips out line feed and carriage return characters from the input html, then extracts the contents of the “mainbox”

, then uses the string.gmatch function to extract the elements of the individual value
's…

Thank you both for your suggested solution.

I tested both scripts to see which one had the fastest run time (tested in LuaTest 1.6)
Akbooer’s solution had a run time of 125.3 ms
Cybrmage solution had a run time of 454.1 ms

Since I only need three values I think I’m going for Akboer’s suggestion since it has the fastest run time. But I’m definitely keeping Cybrmage his suggestion in my bookmarks. I think his suggestion is better when you need the extract a lot of values out an XML file and probably makes up the time then.