Thanks very much Hussein.
In the meantime I had written this pair of macros which use recursion to
calculate a result but I am sure your extension is way more efficient!
Philip Nye
<command name="getNodePosition">
<macro>
<sequence>
<get expression="name($selected)"/>
<command name="countPosition" parameter="%_ 1"/>
</sequence>
</macro>
</command>
<command name="countPosition">
<macro>
<choice>
<sequence>
<command name="selectNode" parameter="preceding %0"/>
<get expression="string(%1 + 1)"/>
<command name="countPosition" parameter="%0 %_"/>
</sequence>
<get expression="%1"/>
</choice>
</macro>
</command>
Hussein Shafie wrote:
> Philip Nye wrote:
>
>>I am trying to build a macro around callouts and <co> elements.
>>
>>Given a selected <co> node, what Xpath expression can I use to calculate
>>what its position (rank) is within the parent element? The result should
>>be the same number that the docbook stylesheet returns for its
>>counter(n) field.
>>
>>Have I have missed something obvious?
>
>
> To my knowledge, there is no XPath function which could give you such rank.
>
> That's why, a few months ago, I've written an extension function for one
> of our customers.
>
> Extension.java:
> ---
> import com.xmlmind.xmledit.doc.XNode;
> import com.xmlmind.xmledit.xpath.EvalException;
> import com.xmlmind.xmledit.xpath.NodeIterator;
>
> public final class Extension {
> public static int indexOfNode(NodeIterator nodeSet,
> NodeIterator node) {
> int index = 0;
>
> try {
> XNode n = node.next();
>
> for (;;) {
> XNode nn = nodeSet.next();
> if (nn == null || nn == n)
> break;
>
> ++index;
> }
> } catch (EvalException ignored) {}
>
> return index;
> }
> }
> ---
>
> To use it:
>
> [1] Copy the attached jar to one of the addon/ directories (or any
> subdirectory) scanned by XXE during its startup.
>
> [2] Declare the namespace in the file containing the macro as follows:
> ---
> xmlns:ext="java:Extension"
> ---
>
> [3] Use it in the <get> element of a <macro>. Example of use (not
> related to your precise need):
> ---
> 1+ext:indexOfNode(//para, $selectedElement)
> ---
>
>
> ------------------------------------------------------------------------
>
> import com.xmlmind.xmledit.doc.XNode;
> import com.xmlmind.xmledit.xpath.EvalException;
> import com.xmlmind.xmledit.xpath.NodeIterator;
>
> public final class Extension {
> public static int indexOfNode(NodeIterator nodeSet,
> NodeIterator node) {
> int index = 0;
>
> try {
> XNode n = node.next();
>
> for (;;) {
> XNode nn = nodeSet.next();
> if (nn == null || nn == n)
> break;
>
> ++index;
> }
> } catch (EvalException ignored) {}
>
> return index;
> }
> }