I have the following sample XML structure:
<SavingAccounts>
<SavingAccount>
<ServiceOnline>yes</ServiceOnline>
<ServiceViaPhone>no</ServiceViaPhone>
</SavingAccount>
<SavingAccount>
<ServiceOnline>no</ServiceOnline>
<ServiceViaPhone>yes</ServiceViaPhone>
</SavingAccount>
</SavingAccounts>
What I need to do is filter the 'SavingAccount' nodes using XPATH where the value of 'ServiceOnline' is 'yes' or the value of 'ServiceViaPhone' is yes.
The XPATH should return me two rows!! I can filter 'SavingAccount' nodes where both of the element values are yes like the following XPATH sample, but what I want to do is an or element value comparison???
/SavingAccounts/SavingAccount/ServiceOnline[text()='yes']/../ServiceViaPhone[text()='yes']/..
This is a very fundamental XPath feature: composing a number of conditions with the logical operators and, or, and the function not().
and has a higher priority than or and both operators have lower priority than the relational and equality operators (=, !=, >, >=, < and <=).
So, it is safe to write: A = B and C = D
Some most frequent mistakes made:
People write AND and/or OR. Remember, XPath is case-sensitive.
People use the | (union) operator instead of or
Lastly, here is my solution:
/SavingAccounts/SavingAccount
[ServiceOnLine='yes' or ServiceViaPhone='yes']
/SavingAccounts/SavingAccount[(ServiceOnLine='yes') or (ServiceViaPhone='yes')]
Will
/SavingAccounts/SavingAccount[ServiceOnline/text()='yes' or ServiceViaPhone/text()='yes']
do the trick?
I have no XPath evaluator handy at the moment.
EDIT:
If I remember correctly, you don't need the text(), so
[ServiceOnline='yes' or ServiceViaPhone='yes']
should be sufficient, and more readable.
EDIT:
Yes, of course, 'or' for predicate expressions, my bad.
Related
Is there any way to evaluate this sum inside the findall/3 clause?
findall((A+C,[M,H|_]),(b_to_b(H,M,C),\+ member(M,[H|T])),R).
Here i get values like (1+3,List) and i'm looking for some shortcut so that i get value 4 instead of (1+3)
I understand what is the problem but a shortcut will be nice otherwise i have to revisit the whole list and that's not nice.
Thanks
Assuming A has already been binded to a numeric, just move the evaluation from the template to the goal:
...,
findall((S,[M,H|_]),(b_to_b(H,M,C),\+ member(M,[H|T]), S is A+C),R).
Efficiency hint: you should also change member/2 to memberchk/2.
In XPath you can use *[position()=1 or position()=last()] to get both the first and last matching node. However, if you want either just the first or last node you can use *[1] or *[last()] respectively. Trying to use something like *[1 or last()] selects all nodes. Is there a more concise way of joining the conditions?
Short answer: No. There is no more concise way than [position()=1 or position()=last()] that make sense for this purpose.
Regarding this predicate that you tried [1 or last()] :
number 0 translated to boolean False and the rest translated to True.
last() returns position index of the last element in context
Given above rules, this kind of predicate expressions [1 or last()] always translated to [True or True] which evaluates to True, that's why you get all nodes using this predicate.
I have an XPATH expression of the following sort that's expected to return a boolean value:
xs:boolean(expression1 or expression2 or expression3)
If expression1 returns true, would the other expressions be evaluated?
In any case could any one point me to examples of how complex logical expressions are written efficiently in XPATH?
BTW: I am running the XPATH on MarkLogic.
In XPath 1.0 it's defined that the expressions are evaluated in order, left to right, until one of them returns true.
But the presence of xs:boolean (which is redundant) in your expression suggests you are using XPath 2.0, and XPath 2.0 processors are allowed to evaluate the subexpressions in any order. This is to allow database-style optimization: one of the subexpressions might be much faster to execute (or more likely to return true) than the others, perhaps because of database indexes, so an optimizer will evaluate that one first. But any decent optimizer will stop evaluation after the first expression that evaluates to "true".
I can't tell you specifically what MarkLogic does.
For anyone else trying this, the "or" operator in XPath must be lower-case.
In light of Michael Kay's comments on optimization, I can't say for sure whether MarkLogic chooses expression to evaluate first or goes left to right, but you can see how a particular XPath is evaluated. In Query Console (usually localhost:8000/qconsole), type in an expression, click the Profile tab, and Run.
//foo[xs:boolean(1 = 1 or 2 = 3)]
The profile tab shows that "1 = 1" is evaluated and "2 = 3" is not.
What is the name of the method corresponding to the ternary operator? By name I mean :+ for addition, :== for equality, etc.
I want to override the ternary operator to build a proxy class (same idea as Javascript proxies) but I can't seem to find the name for this.
There are two names that this is known by, if you are talking about the ? : operator, and that is ternary operator or conditional operator.
But it is not a method, as you can see in this table.
You would need to go to Ruby Source itself to override the behavior. Probably not what you would want to do.
I'm pretty sure it's just known as the ternary operator. Usually people know what you mean when you say that, and I've never heard or seen another name, even during research.
If you mean symbol, I'd call it:
?:
(Question mark, Colon)
My rule requires me to apply them only to methods without 'get' as part of their name. In another words, my rules need to apply to only non-getter methods in the class. I know to get a hold of all the non-getter methods, I can use
//MethodDeclarator[not(contains(#Image,'get'))]
However, I don't know the syntax about where I insert my logic for the rules. Is it like
//MethodDeclarator[
not(contains(#Image,'get'))
'Some Rule Statements'
]
I saw the use of . in the beginning of statement inside [] in some example code. what are they used for?
In my particular case, I need to combine following pieces together but so far I am unable to accomplish it yet.
Piece 1:
//PrimaryExpression[not(PrimarySuffix/Arguments)]
Piece 2:
//MethodDeclarator[not(contains(#Image,'get'))]
Piece 3:
//PrimaryExpression[PrimaryPrefix/#Label='this']
You need to have at least some basic knowledge/understanding of XPath.
I saw the use of . in the beginning of statement inside [] in some
example code. what are they used for?
[] is called predicate. It must contain a boolean expression. It must immediately follow a node-test. This specifies an additional condition for a node that satisfies the node-test to be selected.
For example:
/*/num
selects all elements named num that are children of the top element of the XML document.
However, if we want to select only such num elements, whose value is an odd integer, we add this additional condition inside a predicate:
/*/num[. mod 2 = 1]
Now this last expression selects all elements named num that are children of the top element of the XML document and whose string value represents an odd integer.
. denotes the context node -- this is the node that has been selected so-far (or the starting node off which the complete XPath expression is evaluated).
In my particular case, I need to combine following pieces together ...
You forgot to say in what way / how the three expressions should be combined. In XPath some of the frequently used "combinators" are the operators and, or, and the function not().
For example, if you want to select elements that are selected by all three provided XPath expressions, you can use the and operator:
//PrimaryExpression
[not(PrimarySuffix/Arguments)
and
PrimaryPrefix/#Label='this'
]