A node-set doesn't have order (sets are unordered by definition). Most XPath APIs present the node-set result from evaluating an XPath expression in document order, which is what you observe and report in your question.
XPath is a query (read-only) language and as such it never modifies the structure of the source XML document -- the nodes in the nodeset of selected nodes is the same as their structure in the source XML document. Structure, among other things, includes order.
In case you need the nodes returned in another order than their original order in the XML document, this cannot be done with XPath alone.
One can use XSLT for this purpose:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="library">
<xsl:apply-templates select="*[not(position() >2)]">
<xsl:sort select="position()"
data-type="number" order="descending"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<library>
<book name="book1"> hello </book>
<book name="book2"> world </book>
<book name="book3"> !!! </book>
</library>
the wanted, correct result is produced:
<book name="book2"> world </book>
<book name="book1"> hello </book>