Why does javax.xml.xpath.XPath act differently with a cloned node?
<p>Given the following XML (basic.xml):</p>

<pre><code>&lt;rdr&gt;
  &lt;details&gt;
    &lt;detail&gt;
        &lt;name&gt;version&lt;/name&gt;
        &lt;value&gt;15.0&lt;/value&gt;
    &lt;/detail&gt;
    &lt;detail&gt;
        &lt;name&gt;resolution&lt;/name&gt;
        &lt;value&gt;1080X1920&lt;/value&gt;
    &lt;/detail&gt;
  &lt;/details&gt;
&lt;/rdr&gt;
</code></pre>

<p>I want to get the name and versions out, so I have the following code.  This isn't very tidy, but I have created this for illustrative purposes, but the code does fully function:</p>

<pre><code>import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Example {

    private static XPath factoryXpath = null;

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
        FileInputStream fin = new FileInputStream("basic.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(fin);

        XPathFactory xPathFactory = XPathFactory.newInstance();
        factoryXpath = xPathFactory.newXPath();

        printDetails(document);
    }

    public static void printDetails(Node node) throws XPathExpressionException {
        NodeList nodes = (NodeList) factoryXpath.evaluate("//detail", node, XPathConstants.NODESET);

        printNameAndValue(nodes.item(0));
        printNameAndValue(nodes.item(1));

    }

    public static void printNameAndValue(Node node) throws XPathExpressionException {
        System.out.println("Name=" + (String) factoryXpath.evaluate("//name", node, XPathConstants.STRING));
        System.out.println("Value=" + (String) factoryXpath.evaluate("//value", node, XPathConstants.STRING));
    }

}
</code></pre>

<p>This outputs the following:</p>

<pre><code>Name=version
Value=15.0
Name=version
Value=15.0
</code></pre>

<p>Why does it output the same Name and Value both times?</p>

<p>If I clone the node first, so that printNameAndValue now looks like this:</p>

<pre><code>public static void printNameAndValue(Node node) throws XPathExpressionException {
    Node clonedNode = node.cloneNode(true);
    System.out.println("Name=" + (String) factoryXpath.evaluate("//name", clonedNode, XPathConstants.STRING));
    System.out.println("Value=" + (String) factoryXpath.evaluate("//value", clonedNode, XPathConstants.STRING));
}
</code></pre>

<p>I get the following output:</p>

<pre><code>Name=version
Value=15.0
Name=resolution
Value=1080X1920
</code></pre>

<p>Why does a cloned node act differently?</p>

<p>I removed the cloned node and reverted to the original example where it doesn't work and added the method described here <a href="http://stackoverflow.com/a/2325407/211560">http://stackoverflow.com/a/2325407/211560</a> but with it taking a Node instead of a Document in its attributes.  This prints out the following result:</p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;detail&gt;
        &lt;name&gt;version&lt;/name&gt;
        &lt;value&gt;15.0&lt;/value&gt;
    &lt;/detail&gt;
Name=version
Value=15.0
&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;detail&gt;
        &lt;name&gt;resolution&lt;/name&gt;
        &lt;value&gt;1080X1920&lt;/value&gt;
    &lt;/detail&gt;
Name=version
Value=15.0
</code></pre>

<p>It is clear from this that the node is the one we would expect; but it is applying the XPath to the first node, or maybe to the original document.  I'm OK with cloning a node and using that but I'd really like to know why this is happening.</p>
