Re: [xml] xpath question



Probably you need to switch to fresh version of libxml2.
I tried your example using following file :

[aleksey pc tmp]$ more t.xml
<xmlsysd>
  <proc>
    <stat tv_sec="1015338699" tv_usec="976442">
    <cpu id="-1">
        <user>5194912</user>
        <nice>8321</nice>
        <sys>500654</sys>
        <tot>466938748</tot>
    </cpu>
    <cpu id="0">
        <user>5194912</user>
            <nice>8321</nice>
    </cpu>
    </stat>
  </proc>     
</xmlsysd>

and it works just fine:
[aleksey pc tmp]$ xmllint --shell t.xml
/ > xpath /xmlsysd/proc/stat/cpu[ id='0']/user
Object is a Node Set :
Set contains 1 nodes:
1  ELEMENT user
/ > xpath /xmlsysd/proc/stat/cpu[1]/user

Object is a Node Set :
Set contains 1 nodes:
1  ELEMENT user


Aleksey.


Robert G. Brown wrote:
Dear libxml experts,

I'm using libxml to rewrite a system information daemon for use in the
context of beowulfery or lan management that (upon request) parses the
mess that is proc and presents it read-only via a socket/daemon to
clients that might wish to monitor e.g. loadavg, cpu consumption, memory
consumption in a lightweight way on a remote host.

I use libxml to pack all the "interesting" parsed information into a
message sent by the daemon. You can view a tentative early-alpha
version of the output generated via:

telnet rgb.adsl.duke.edu 7887

and enter

init
send
send
...
quit

after connecting to see a typical client cycle with some suitable
polling interval, e.g. 10 seconds.

My question/problem arises from attempting to write a client that sends
the init/send/send... and receives the XML messages sent by the daemon
and then parses and unpacks them i nto suitable structs. Initially I'm
trying to write a simple multihost version of "vmstat" that reads from
the sockets instead of parsing /proc directly, but eventually the data
unpacking will be used to drive a much more powerful GUI application
that can display, graph, etc the results.

Reading in the message and putting it into an xmlDoc is no problem.
However, for a variety of reasons (homology of sorts to the mess that is
/proc, ability to avoid dozens of tedious passes through xmlDoc,
scalability of the code API) I've been trying to use xpath rather than
the generic parsing given in the online example(s) to extract the values
from the xmlDocs for each host. There I encounter a problem. I don't
know if it is a bug or just a weakness in my understanding of the xpath
API, so I submit it for your consideration.

First let me note that I'm using e.g.

http://www.zvon.org/xxl/XPathTutorial/Output/example[1-22].html

as documentation for what constitutes a valid xpath _expression_. From
this it appears to be quite simple to explicitly define an xpath to each
field I need to extract and extract its contents, and indeed so it
proves to be for any "simple" xpath _expression_ such as:

"/xmlsysd/system/users"

However, there are certain tags (such as "/xmlsysd/proc/stat/cpu") that
appear several times on a single processor or multiple processor host
and which wrap a collection of individually tagged fieds (./user,
./nice, ...). These cpu tags are differentiated by an id='' attribute.
Eventually I may differentiate similarly tagged e.g. eth0, eth1... and
disks the same way.

According to the xpath tutorial above, I "should" be able to access
these fields according to their attribute with an _expression_ such as:

"/xmlsysd/proc/stat/cpu[ id ='0']/user"

to get

<xmlsysd>
...
<proc>
<stat tv_sec="1015338699" tv_usec="976442">
<cpu id="-1">
<user>5194912</user>
<nice>8321</nice>
<sys>500654</sys>
<tot>466938748</tot>
</cpu>
<cpu id="0">
<user>5194912</user> <----*
<nice>8321</nice>

At the very least, if I use an xpath _expression_ like:

"/xmlsysd/proc/stat/cpu[ id='0']"

I should get to the <cpu id="0"> tag and have only to parse out the
contents of <user> the "hard way".

When I attempt this (either way) in C, I get the following:

Error xpath.c:1091: Invalid operand
/xmlsysd/proc/stat/cpu[ id='0']
^
xmlXPathEval: 1 object left on the stack

when attempting to execute:

xp_op = xmlXPa thEval((const xmlChar *) "/xmlsysd/proc/stat/cpu[ id='0']",
xp_doc);

(where xp_op is the xmlXPathObjectPtr and xp_doc the xmlXPathContextPtr
associated with the xmlDoc, all nicely initialized and demonstrably
functional for even complex xpath expressions such as

"/xmlsysd/proc/stat/cpu[1]/user"

.)

Xpath expressions such as "//cpu", "//cpu[ id='0']" or "//cpu[1]/user"
also appear to fail, but they fail differently. Instead of getting a
stack error within xmlXPathEval I get a segmentation fault, almost
certainly within xmlXPathEval itself since I fail to get to a debugging
output statement immediately following the call in my code.

FWIW, I'm working on RH 7.1 and RH 7.2 systems with

libxml-1.8.17-1
or libxml-1.8.10-1

installed -- the problem occurs in both.

Any help on this would be greatly appreciated. I'm pretty sure that I
can hack something together that w ill work -- heck, I can always fall
back on a mix of xpath and straight xmlDoc parsing or xmlDoc parsing
alone -- but it seems like the xmlXPathEval command might be broken
since several of the things I tested are structurally right off the xml
tutorial page.

BTW, note that in this particular application I don't really expect
there to ever exist a DTD and so forth for the xml defined (although
there might be, if somebody ever wants to write a web-app to directly
access the daemon's output). My concerns are therefore pretty
specifically how to get the c library xpath calls to handle expressions
with e.g. attributes or //tag formats.

rgb




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]