xpath to get the entire xml tree structure

15.7k Views Asked by At

Is there a way using xpath to obtain the entire tree structure. For example, say this is the xml

<a>
   <b>
      <c>
         data
      </c>
   </b>
</a>

I would like the xpath to pick up all the contents of the node and the result should be

  <b>
     <c>
        data
     </c>
  </b>

I have been using VTD-XML and java so far to retrieve the elements so far. This is the code I have been using.

    VTDGen vg = new VTDGen();
    vg.setDoc(xmlString);
    vg.parse(true);
    VTDNav vn = vg.getNav();
    AutoPilot ap = new AutoPilot(vn);
    ap.selectXPath(xPath);
    String data = ap.evalXPathToString();
4

There are 4 best solutions below

0
On

Remember that XPath selects a node or set of nodes. Think of it as returning pointers into your original source tree. It doesn't return "the entire tree structure", it returns pointers to selected nodes in that structure. Whatever you select, the whole structure is available to your program by navigating from the selected nodes to others. That navigation can be done using further XPath expressions, or using a DOM-like navigational API, or implicitly by operations such as serialization (typically when you serialize a node, it shows the whole subtree rooted at that node).

1
On

Ideally, "//b" selects nodes in the document from the current node that match the selection.

0
On

Use:

/*/node()

This selects all children nodes of the top element of the XML document. The set of all these nodes has exactly the wanted subtree structure because every selected element preserves its entire sub-tree (of which this element is the top-node).

XSLT-based verification:

<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="/">
  <xsl:copy-of select="/*/node()"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<a>
  <b>
     <c>
      data
     </c>
  </b>
</a>

the XPath expression is evaluated and the selected nodes are output, producing the wanted, correct result:

<b>
   <c>
      data
     </c>
</b>
0
On

Use

/descendant-or-self::node()