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="email@example.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
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!
Open Group Certified Distinguished IT Architect. Open Group Certified Master IT Architect. Sun Certified Architect (SCEA).
Joined: Feb 21, 2002
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