Home All Groups Group Topic Archive Search About

Trying to evaluate xpath myself sort-of

Author
16 Nov 2007 4:16 AM
David Thielen
Hi;

In our program we will get an XPath statement such as:
${data}/SalesProject[customer/CUSTCAT=${series}/customer/CUSTCAT]

Where ${data} and ${series} both stand for a XPathNavigator so each is
basically a specific node in a list of nodes that another XPath statement is
returning.

To evaluate this we basically build from the right to the left, stripping
off ]) fromt he far right to keep it balanced. So we do:

string str = navSeries.SelectSingleNode("self::node()/customer/CUSTCAT");
object value =
navData.SelectSingleNode("self::node()/}/SalesProject[customer/CUSTCAT=" +
str);

And the above works great. But, the whle thing falls apart when the XPath
passed in is:
count(${data}/SalesProject[customer/CUSTCAT=${series}/customer/CUSTCAT])

because that becomes count("abc") - if the first node that matches the inner
part above is "abc".

So, any idea on how to handle this so that count will work?

We are iterating through navSeries and for each navSeries entry we create
and iterate through navData and for each of those iterations we need to run
the inner XPath and return it's value (to place in a report).

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm

Author
16 Nov 2007 1:32 PM
WenYuan Wang [MSFT]
Hello Dave,

We need to perform more research on this issue . We will reply here as soon
as possible.
If you have any more concerns on it, please feel free to post here.

Thanks for your understanding!
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
19 Nov 2007 8:59 AM
WenYuan Wang [MSFT]
Hello Dave
Thanks for your waiting.

I'm sorry, but I'm not sure I have understood this issue completely.
Could you say more about what you mean about evaluating the XPath yourself,
please?

I think in order to do this you will need to build a parse tree of the
expression then evaluate it accordingly.

i.e.
count(${data}/salesproject[customer/custcat=${series}/customer/custcat])
would become (my made up syntax)

eval_expression = count
                eval_variable = ${data} 
                                eval_xpath = data/salesproject
                                                eval_expression = filter
                                                                eval_xpath
= customer/custcat

eval_variable = ${series}

    eval_xpath = /customer/custcat

Walk the tree evaluating each XPath, expression or variable substitution.

Or

We could write code that knows how to replace ${} variables with the actual
value then use XPathNavigator.Evaluate() to eval the expression.

Hope this helps.
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
19 Nov 2007 4:38 PM
David Thielen
Yes, I am doing what you suggest in breaking it out. The problem is, how do I
know that count wants a list of nodes as opposed to the node value?

I would like to replace the ${var} value with the actual value - but it is
to an XPathNavigator element so how do I get the xpath that represents the
present node on for an XPathNavigator object?

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm




Show quote
"WenYuan Wang [MSFT]" wrote:

> Hello Dave
> Thanks for your waiting.
>
> I'm sorry, but I'm not sure I have understood this issue completely.
> Could you say more about what you mean about evaluating the XPath yourself,
> please?
>
> I think in order to do this you will need to build a parse tree of the
> expression then evaluate it accordingly.
>
> i.e.
> count(${data}/salesproject[customer/custcat=${series}/customer/custcat])
> would become (my made up syntax)
>
> eval_expression = count
>                 eval_variable = ${data} 
>                                 eval_xpath = data/salesproject
>                                                 eval_expression = filter
>                                                                 eval_xpath
> = customer/custcat
>                                                                
> eval_variable = ${series}
>                                                                            
>     eval_xpath = /customer/custcat
>
> Walk the tree evaluating each XPath, expression or variable substitution.
>
> Or
>
> We could write code that knows how to replace ${} variables with the actual
> value then use XPathNavigator.Evaluate() to eval the expression.
>
> Hope this helps.
> Best regards,
>
> Wen Yuan
> Microsoft Online Community Support
> ==================================================
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>
Author
20 Nov 2007 11:22 AM
WenYuan Wang [MSFT]
Hello Dave,
Thanks for your reply.

> how do I know that count wants a list of nodes as opposed to the node
value?
We may check it by ourself. If eval_expression is "count", we need a list
of nodes instead of node.

>how do I get the xpath that represents the present node on for an
XPathNavigator object?
I'm afraid it is different to get XPath from current node. But we can
retrieve it from the Root element. For example:

static public string getXpath(XPathNavigator xpn)
        {           
            StringBuilder sb = new StringBuilder();
            do
            {
                if (xpn.NodeType == XPathNodeType.Root)
                {
                    sb.Insert(0, "/");
                    break;
                }

                if (xpn.NodeType == XPathNodeType.Element)
                {
                    int position = getPosition(xpn.Clone());               

                    sb.Insert(0,
string.Format("/{0}[{1}]",xpn.Name,position));
                    continue;
                }
            }
            while (xpn.MoveToParent());
            return sb.ToString();
        }

        static public int getPosition(XPathNavigator xpn)
        {
            int position =1;
            while (xpn.MoveToPrevious())
                position++;
            return position;
        }


Hope this helps. Please feel free to update here again, if there is
anything we can help with. We are glad to assist you.

Have a great day,
Best regards,

Wen Yuan
Microsoft Online Community Support
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

AddThis Social Bookmark Button