Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Programatically identifying iterating nodes...

 
Byron Estes
Ranch Hand
Posts: 313
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I started really working with DOM and XPath a couple of weeks ago. I wrote some classes that allow me to pass in an xml document and an element name (...as a String) and have it generate the xpath location for me. I've done this for elements and attributes, but I'd like to add another feature. I'd like to insert "[?]" after every repeating node.
For example lets say we have...
<?xml version="1.0" encoding="UTF-8"?>
<PurchaseOrder orderDate="Oct 30, 2000">
<ShipTo city="San Jose" name="Fox Mulder" state="California" street="47 Rosedale Drive" zip="56789"></ShipTo>
<Contact contactEmail="bobsmith@ca.ibm.com" contactName="Bob Smith" contactPhone="416-448-4414"></Contact>
<Items>
<Item>
<ProductName>TShirts</ProductName>
<quantity>50</quantity>
<price>20</price>
<SubItem>
<orderno>9876</orderno>
<desc>Sub Item A</desc>
</SubItem>
</Item>
<Item>
<ProductName>Tennis balls</ProductName>
<quantity>500</quantity>
<price>3</price>
<SubItem>
<orderno>12341</orderno>
<desc>Sub Item One</desc>
</SubItem>
<SubItem>
<orderno>12342</orderno>
<desc>Sub Item Two</desc>
</SubItem>
<SubItem>
<orderno>12343</orderno>
<desc>Sub Item Three</desc>
</SubItem>
</Item>
</Items>
</PurchaseOrder>
Right now if I ask it to give me the location path for "quantity", it returns...
/PurchaseOrder/Items/Item/quantity
....which is correct, but what I'd like to do is have it send back
/PurchaseOrder/Items/Item[?]/quantity
Any ideas how you can idenfity nodes like "Item" that begin a repeating structure?
Regards,
Byron
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you get
PurchaseOrder/Items/Item/quantity
you can easily get to
PurchaseOrder/Items/Item
because it is the parent of ../quantity. DOM api has functions to navigate "up" the tree.
However, PurchaseOrder/Items/Item is not the same as /PurchaseOrder/Items/Item[?]/quantity
This is becasue Item[?] node is not found in the original tree.

You can get all repeating Items/Item nodes by using the name of the nearest parent that also has a repeating structure. In your example that happens to be the element "Item" itself.
Using Document.getElementsByTagName("Item") on the Document object returned by DOM parsers you can retrieve a NodeList of nodes, each pointing to an <Item> node. You can loop through the NodeList as you would do with any standard collection and process each <Item> node as requried.
Hope that helps!
 
Byron Estes
Ranch Hand
Posts: 313
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ajith, I appreciate your response, but I think you may have misunderstood my question because I've done essentially what you said (i.e. use the getParent()) to generate the xpath location from any childNode.
The issue I'm trying to deal with is the ability to generate an xpath location string with the position notation already stuck in at the appropriate places with a "?" to be the placeholder for the position itself. I want to do this to simplify the creation of xpath location paths to "surgically" extract a given piece of data. I realize this is not going to be efficient for some types of processing, but for some purposes it would be ideal.
Using replacement or regular expressions I could alter the position parameters in the path, execute the xpath on a DOM object and pull out the nth occurence of quantity (..or any other element in the repeating structure).
I already have another solution that I think will work that does not require my xpath location generation class to find the nodes that need position notation.
The helper class I created is more generic and should satisfy this need. I called the class XPathLocation. It has a constructor that takes in a path (String) without positional notation. It has a method nthOfX(int position, int step). Where the position is the occurence that you are looking for and step is the node path to place the occurence/position notation on. You can call nthOfX() as many times as you like to place multiple positions. Under the covers StringBuffers and StringTokenizer rework the raw path and toString()method spits out the modified xpath string with positional notation.
Regards,
Byron
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic