XPath query result order
I could find the following bug-report which looks like the issue: Bug 363252 - proximity position in libxml2's xmlXPathEvalExpression() reported 18 Oct 2006 and confirmed dating back since May 2006 which is before the 2.6.26 version in question.
This should have been fixed in libxml2 2.6.27.
XPATH -- Result order defined by query
The |
operator computes the union of its operands and with XPath 1.0 you simply get a set of nodes, the order is undefined, though most XPath APIs then return the result in document order or allow you to say which order you want or whether order matters (see for instance http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult).
With XPath 2.0 you get a sequence of nodes ordered in document order, with XPath 2.0 if you want the order of your subexpressions you would need to use the comma operator, not the union operator i.e. element[@attr="a"] , element[@attr="b"] , element[@attr="c"]
.
Sorting XPath results in the same order as multiple select parameters
An XSLT example:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="pSequence" select="'2 1'"/>
<xsl:template match="objects">
<xsl:for-each select="object[contains(concat(' ',$pSequence,' '),
concat(' ',@uid,' '))]">
<xsl:sort select="substring-before(concat(' ',$pSequence,' '),
concat(' ',@uid,' '))"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output:
<object uid="2" /><object uid="1" />
Sorting Results returned by SimpleXML, and Xpath in PHP
You can probably do it with XPath or something, but SimpleXMLElement::xpath()
returns an array that is easy to sort:
usort($xQuery, function ($a, $b) { return strcmp($a->Make, $b->Make); });
foreach ($xQuery as $results) {
// …
}
How do I guarantee node order for an XPath 'OR' query
As I understand it, .NET supports
XPath 1.0 which does not guarantee
node order
When an XPath 1.0 expression that selects nodes is evaluated, the selected nodes form a node-set. A node-set is a set and this, among many other things, means that it is unordered.
For practical purposes, though, there is one main ordering chosen to enumerate the nodes of a node set: document order. In practice, all XPath 1.0 engines I know (and certainly in .NET) return the selected nodes in document order. In the future this is unlikely to change, because vendors try to preserve backwards compatibility.
Therefore, just try using the SelectNodes()
or Evaluate()
methods and verify that the nodes in the results are in document order.
Do note: The order of the following cannot be guaranteed and is implementation-dependent:
Attributes of the same element.
Nodes belonging to different documents (a node-set containing nodes from different documents can be produced using the XSLT function
document()
, so this most probably is of no concern to you).
Xpath 1.0 query to sorting and extract minimum date value doesn't work
The <
and >
operators in XPath 1.0 are defined only on numbers, not on strings (or dates/times). If you use them on strings, the system will attempt to convert strings to numbers, generally resulting in a NaN < NaN
comparison, which is always false.
For comparing dates a popular XPath 1.0 workaround is to strip out the punctuation and then compare say 20190430 and 20190101 as numbers.
How to sort values via XPath
You can use xsl:sort
to sort matching nodes. This will allow you to sort by your val
element. However, XPath 1.0 does not have a date data-type. A reasonable solution to this problemm is to split your date into its year, month and day components and sort by each individually. The following should do the trick:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates>
<xsl:sort select="val" data-type="number" order="descending"/>
<!-- year sort -->
<xsl:sort select="substring(date,7,4)" data-type="number" />
<!-- month sort -->
<xsl:sort select="substring(date,4,2)" data-type="number" />
<!-- day sort -->
<xsl:sort select="substring(date,1,2)" data-type="number" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Related Topics
What Means Call to a Member Function on Boolean and How to Fix
Why Is My Number Value Changing Using Number_Format()
PHP Timezone Database Is Corrupt Error
Multi Checkbox Fields in Woocommerce Backend
Execute PHP Script Before Every PHP Script
Modify an Existing PHP Function to Return a String
How to Get Attribute of Node with Namespace Using Simplexml
Converting a Postman Request to Curl
Laravel: Where to Store Global Arrays Data and Constants
Protocol Https Not Supported or Disabled in Libcurl
How to Create Clean Url Using .Htaccess
Laravel 4.1: How to Paginate Eloquent Eager Relationship
How to Extract HTML Comments and All HTML Contained by Node
PHP Undefined Index Error $_Files
How to Do Url Rewriting in PHP
Parse Select Clause of SQL Queries into a PHP Array
Laravel: I Can't Send More Then 2 Variables from Controller to a View