question

GregM avatar image
GregM asked ericnute edited

How to return an index from an XPATH search

Given a table, such as:

 

col1 col2

a       w

b       x

c       y

d       z

e       t

 

Is there an XPATH query to obtain the row index based on column content?  The following XPATH will find the row of interest:

 

//row[col1 = 'c']

 

What I'm looking for is an XPATH function that would return 2 for say, position(//row[col1 = 'c']).  Is there such a thing or another apporach?

 

iTestresponse mapxpath
10 |950

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
GregM avatar image
GregM answered GregM posted

Here's the solution:  count(//row[col1 = 'c']/preceding-sibling::*)

 

Thanks to

 

http://www.eggheadcafe.com/forumarchives/NETxml/Oct2005/post24414973.asp

and

http://www.zvon.org/xxl/XPathTutorial/Output/example16.html

 

6 comments
10 |950

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

dclaar avatar image dclaar commented ·

Trying to do something similar, but having problems. Given a pattern to match this:

0x0000: 0004 23cb 67a5 000c bd00 87b2 0806 0001 ..#.g...........

 

Because table fails, and block fails...

 

Anyway, the pattern is "table_pattern", and the tokens are "address", "data1"..."data8", and "ascii".

This is for tcpdump, whose output looks like:

02:56:40.701565 IP (tos 0x0, ttl 1, id 0, offset 0, flags [DF], proto: ICMP (1), length: 212) 10.1.254.20 > 10.1.254.30: ICMP echo request, id 48877, seq 25, length 192 0x0000: 0004 23b0 6e07 00e0 ed11 b710 0800 4500 ..#.n.........E. 0x0010: 00d4 0000 4000 0101 68f4 0a01 fe14 0a01 ....@...h....... 0x0020: fe1e 0800 38f9 beed 0019 0000 0000 0000 ....8........... 0x0030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0x0040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0x0050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 02:56:40.701578 IP (tos 0x0, ttl 64, id 7134, offset 0, flags [none], proto: ICMP (1), length: 212) 10.1.254.30 > 10.1.254.20: ICMP echo reply, id 48877, seq 25, length 192 0x0000: 00e0 ed11 b710 0004 23b0 6e07 0800 4500 ........#.n...E. 0x0010: 00d4 1bde 0000 4001 4e16 0a01 fe1e 0a01 ......@.N....... 0x0020: fe14 0000 40f9 beed 0019 0000 0000 0000 ....@........... 0x0030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0x0040: 0000 0000 0000 0000 0000 0000 0000 0000 ................

 

What I want to do is identify the packet with 4500 in data8 in the row with address 0x0000, and then verify that data4 in the row with address 0x0020 is "beed".

This would be a lot easier with a table, but the problem is that tcpdump can throw arbitrary data between the timestamp line and the beginning of the data dump, which causes the table to fail.

I've got as far as finding the first part, with

//table_pattern[address='{0}'][data8='{2}']

And I get back 4500. But I can't get it to return the number of the instance, so that I can then look at the packet.

 

 

0 Likes 0 ·
dclaar avatar image dclaar dclaar commented ·
Went back to a table, and used response map filtering. So I don't need this answered. It was a bit annoying though...tcpdump is a pain in the tail to map!
0 Likes 0 ·
GregM avatar image GregM dclaar commented ·

First of all, this response works okay with a table, just make the packet timestamp row the header with regex \d{2}:\d{2}.* 

 

The expression //table[row[address = '0x0000:' and data8='4500'] and row[address = '0x0020:' and data4 = 'beed']] will list all the tables which match the criteria you specified.  You can read this expression as "return the table(s) for which one of its rows both address=0x0000: and data=4500 and another row with 0x0020 and data4=beed.

0 Likes 0 ·
tcpDump.ffrm (132.3 KiB)
dclaar avatar image dclaar GregM commented ·

Well, yes, for the response I copied, a table works. As I said, however, tcpdump can put random stuff after the timestamp, as in this case:

02:56:32.452762 IP6 (hlim 255, next-header: ICMPv6 (58), length: 16) fe80::204:23ff:fed6:ac0a > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 16 source link-address option (1), length 8 (1): 00:04:23:d6:ac:0a 0x0000: 0004 23d6 ac0a 0x0000: 3333 0000 0002 0004 23d6 ac0a 8100 0064 33......#......d 0x0010: 86dd 6000 0000 0010 3aff fe80 0000 0000 ..`.....:....... 0x0020: 0000 0204 23ff fed6 ac0a ff02 0000 0000 ....#........... 0x0030: 0000 0000 0000 0000 0002 8500 db64 0000 .............d.. 0x0040: 0000 0101 0004 23d6 ac0a ......#...

That was what drove me to patterns. But I couldn't get the patterns to go, so I went to response filtering. Once I filtered in only what I wanted to deal with, then the table stuff worked fine.

 

Thanks for the example, though!

 

 

0 Likes 0 ·
GregM avatar image GregM dclaar commented ·

Wow, the response filter is very useful - keep only what's relevant to your table:

regex (\t0x.*)|(\d{2}:\d{2}.*)

 

It seems the response map editor does not apply the filter on its sample data, so you have to have a test case to see the result of the filter.  Oh well, pretty good for a first implementation of the feature.  I'll request an enhancement.

0 Likes 0 ·
tcpDump.zip (8.0 KiB)
dclaar avatar image dclaar GregM commented ·

While you're in the enhancement filing business, can you file an enhancement for the ability to "or" inclusion? I think I mentioned this elsewhere...

If you look at tcpdump:

15:25:37.322832 arp who-has 10.2.1.5 tell 10.2.1.45 0x0000: 0004 23cb 67a5 000c bd00 87b2 0806 0001 ..#.g........... 0x0010: 0800 0604 0001 000c bd00 87b2 0a02 012d ...............- 0x0020: 0000 0000 0000 0a02 0105 .......... 15:25:37.322965 arp reply 10.2.1.5 is-at 00:04:23:cb:67:a5 0x0000: 000c bd00 87b2 0004 23cb 67a5 0806 0001 ........#.g..... 0x0010: 0800 0604 0002 0004 23cb 67a5 0a02 0105 ........#.g..... 0x0020: 000c bd00 87b2 0a02 012d 0000 0000 0000 .........-...... 0x0030: 0000 0000 0000 0000 0000 0000 ............ 8 packets captured 8 packets received by filter 0 packets dropped by kernel

There are several things to keep. One is the timestamp, so that you can find tables. Another is the table itself. And finally, the statistics at the bottom. Right now, there's no good way to do this if you don't know what to exclude. So I have an include with the RE:

 

(^\d\d:\d\d:\d\d\.\d+\s)|(^\t0x[\dA-Fa-f]{4}:\s+([\s\dA-Fa-f]{4}\s){8}\s[^\n\r]{16})|^\d+ packets (captured|received|dropped)

Yeah, it works, but it would be really nice to be able to do "or" on includes, and "and" on excludes. If you think about it, the response filter might apply the excludes in order, but that is functionally a logical and. And doing a logical and on includes just doesn't make sense.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.