Is there are more concise way than using position() for multiple conditions in XPath? - xpath

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.

Related

Evaluating an expression in the head of the clause

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.

Logical expression evaluation in Xpath

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.

How to have nested conditions for PMD Xpath rules

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'
]

Sort NSFetchRequest by a predicate

I have a SQLite-backed core data storage and would like to fetch a list of managed objects using NSFetchRequest. I want said list to be sorted by a boolean value that can be easily calculated at the database level. I know this because it’s possible to formulate the same conditions using an NSPredicate, which would look as follows:
[NSPredicate predicateWithFormat:#"uid = %#", currentUID]
Sadly, there seems to be no way to formulate a condition like this using an NSSortDescriptor. How do I best go about this? Do I fetch two lists, one with
[NSPredicate predicateWithFormat:#"uid = %#", currentUID]
and one with
[NSPredicate predicateWithFormat:#"uid != %#", currentUID]
and combine them later on? Can I then still elegantly use a NSFetchedResultsController?
Or should I fetch all items and sort them later in code? Or is there anything I’ve missed.
Just create an array (even if it contains only a single element) of NSSortDescriptors to sort the result as desired.
You use setSortDescriptors: to set them.
The fetch can handle both predicates and sorting at the same time.
What you're asking for doesn't make sense.
A predicate is used to select which objects should be returned in a set of results. This is determined by evaluating the predicate against each object to see if the predicate evaluates to YES or NO (a binary value, or one of 2 possible values). If it evaluates to YES, then the object is included. If it evaluates to NO, then the object is excluded. There is no middle ground.
By contrast, a sort descriptor evaluates to less than, equal, or greater than. In other words, it is a ternary value (it can be one of 3 things). There is no way to express a ternary value with a predicate (since a predicate is binary), and so using a predicate as a sort descriptor makes absolutely no sense. The API doesn't allow it, because logic doesn't allow it.
So the real question is: what are you trying to do? Why do you think you need a predicate in your sort descriptors?

XPATH Multiple Element Filters

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.

Resources