VTD-XML Home
|
3. Navigate VTD
After parsing, VTDNav has
two views of VTD tokens: flat and hierarchical.
-
Flat view:
In
this view, one is able to access individual VTD records one after the other.
Because
a VTD record is stored in array-like buffers, it is addressable using an
integer. As a result of
this design, many member methods, e.g. getTokenLength, matchTokenString,
takes the VTD index as
the input. The following code snippet will print out token types, length and
offset of every VTD
records.
// Assuming parsing is successful
// vn is an instance of VTDNav
int size = vn.getTokenCount();
for (int i= 0;i<size;i++)
{
System.out.println("token count => "+i);
System.out.println("token type =>" + vn.getTokenType(i));
System.out.println("token offset => "+ vn.getTokenOffset(i));
System.out.println("token length => "+ vn.getTokenLength(i));
}
|
-
Cursor-based
hierarchical view:
In this view, one navigates the cursor across the
hierarchy. However, one should notice that this hierarchy is for elements
only; in other words, in our processing, we only consider elements as part
of the hierarchy, and treats text node, CDATA and attributes as belongings
of an element. Also there is one and only one global cursor available.
Duplicate of this cursor is disallowed. To record the position of a cursor,
one can either save the VTD index value or push the cursor value into a
global stack, and later pop it back. The following code snippet navigates a
very simple XML document and prints out value of interest.
/* Sample XML
<contact>
<firstname> Charley </firstname>
<lastname> Wang </lastname>
<PhoneNumber location="home"> 100-100-100 </PhoneNumber>
</contact>
*/
// After parsing, the cursor is always at the root element
try {
if (vn.matchElement("contact")) // test the element name of the root
{
//Get first child element of the name "firstname"
if (vn.toElement(VTDNav.FIRST_CHILD,"firstname"))
{
int t = vn.getText();
if (t!=-1) //test to see if the element has text node or not
System.out.println(" first name ==> "+
vn.toString(t));
// navigate to element "PhoneNumber"
if (vn.toElement(VTDNav.NEXT_CHILD,"PhoneNumber"))
{
int a = vn.getAttrVal("location");
int t = vn.getText();
if (a!=-1 || t!= -1)
{
System.out.println(" Phone number @"+ vn.toNormalizedString(a)
+ " is ==> " + vn.toNormalizedString(t));}
}
}
}
}
catch (NavException e){ // handle errors here}
|
In the example shown above, the user moves the cursor
manually across the element hierarchy. The other mode of navigation is by
using "AutoPilot." The example below shows how to perform a depth-first
document order node iteration. During the iteration, if one moves the cursor
for any reason, he must make sure that he moves the cursor back before the
next iteration. This is because VTDNav only have one global cursor, and when
the cursor changes position, it doesn't know (or care) whether it is moved
manually or by AutoPilot.
// assume vn is already available
try {
AutoPilot ap = new AutoPilot(vn); // ap is going to move the
cursor
ap.selectElement("*"); // select every element (* matches all
strings)
while( ap.iterate() ) // iterate will iterate thru all
elements
{
// put processing logic here
System.out.println("Element name ==> " +
vn.toString(vn.getCurrentIndex()));
int t = vn.getText();
if (t!=-1)
System.out.println("Text
content ==> " + vn.toNormalizedString(t));
// make sure that the
cursor position entering the loop is the same
// as the position
exiting the loop
// One way to do is use
teh combination of vn.push() and vn.pop()
// The other is to
manually move the cursor back into the original place
}
vn.toElement(VTDNav.ROOT);
// reset the cursor to point to
the root element
} catch ( PilotException e){
// handle exception here
} catch ( NavException e){
// handle exception here
}
|
|