Programmatically implementing a Complex XPath Query

L

Lance M

Hi all,

I am trying to programatically execute a complex XPath query that will
filter a field for me. I have 2 dataconnections (connectionA and
ConnectionB), each linking to a form library with over 1500 infopath
forms each. Both of these forms (for A and B) have the same field
(BatchNum). The scenario is this: form A is completed before form B,
and I want to figure out which BatchNums from form A are ready to be
used within form B. What I want to do is execute a single XPath query
to filter these out, something like:

selectNodes("/dfs:myFields/dfs:dataFields/dsf:A[@BatchNum " + _
"!= /dfs:myFields/dfs:dataFields/dsf:B/@BatchNum]")

This query of course does not work (but it gives you the idea). Are
there any good examples out there for filtering with XPath? This
problem requires nested queries (one of which must reference a node
outside of it). Is this possible? Are there any good examples of XPath
out there that are more involved than the simple book/title/@crapiola?

Also, so as not to limit the feedback, are there any other ways to
filter that would be as fast as XPath? I can iteratively filter, but
that takes time because there are a lot of documents to scroll through.
Any thoughts would be appreciated. Also, if you need more info let me
know.

Lance M.
 
G

Greg Collins [InfoPath MVP]

Why not first get the value of B's BachNum attribute and then just insert that into your select statement.

(Sorry, the following is JScript, but it should be simple enough to convert it to VBScript)

var bn = XDocument.DOM.selectSingnleNode("/dfs:myFields/dfs:dataFields/dfs:B/@BatchNum");
var a_nodes = XDocument.DOM.selectNodes("/dfs:myFields/dfs:dataFields/dfs:A[@BatchNum = '" + bn + "']");
 
L

Lance M

Hi Greg,

Thanks for the reply. I should elaborate a little more, I think. What
your code is doing is selecting a single node from B, and then finding
all nodes that match it within A. This process would have to be
repeated iteratively mutliple times until each of the form libraries
has been filtered because I would need to compare all the B's to all
the A's(this will be the solution I use unless I can find out how to do
all the filtering in one xpath query). This is not so bad, and it does
speed up things currently, but the way we are using form libraries
means that running through that many forms will bloat the load time for
each form that a user opens. I know how to filter it theoretically, but
I am hung up on the xpath. I will show you some code that I have, what
it is supposed to do, and the problem I encountered with it:

selectNodes("/dfs:myFields/dfs:dataFields/dfs:A[@BatchNum[/dfs:myFields/dfs:dataFields/dfs:B[@BatchNum
= @ABatchNum] != .]")

and by @ABatchNum I am referencing the @BatchNum for A, on the
outermost filter level. Logically, what this code does is it selects
all nodes from A whose BatchNum is filtered on [the BatchNum from B
filtered on [the B BatchNum = the current A BatchNum being looked at by
the filter] != the current A BatchNum]

Verbally, this finds all the BatchNums in B that = those in A, and then
inverts it. I use the inverting on the outside of the B filter so that
the A filter has a boolean comparison inside (I am not sure if this is
necessary with Xpath, or if a null object would make it false too) .

My real problem with the above code is that @ABatchNum really has the
name @BatchNum, and I do not know how to reference it inside of the
Xpath while filtering on another unique attribute that happens to have
the same name (i.e. @BatchNum = @BatchNum <--?This would compare it to
itself!). I cannot use Ancestor or preceding, I cannot use the . symbol
because it will refer back to B, and I do not know what xpath functions
the .selectNodes function allows.

I remember that I found out how to do this with the filtering tools in
Infopath itself a long time ago, but because of other problems with
infopath ( it slowed it down so bad) I had to use alternative methods.
The Xpath infopath uses is different from what I have seen for xpath
examples, and as such I do not know how to move it over to code, or
even if it can be moved.

I hope all that made sense!

Lance M.
Why not first get the value of B's BachNum attribute and then just insert that into your select statement.

(Sorry, the following is JScript, but it should be simple enough to convert it to VBScript)

var bn = XDocument.DOM.selectSingnleNode("/dfs:myFields/dfs:dataFields/dfs:B/@BatchNum");
var a_nodes = XDocument.DOM.selectNodes("/dfs:myFields/dfs:dataFields/dfs:A[@BatchNum = '" + bn + "']");
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top