I'm interested in advice/pseudocode code/explanation rather than actual implementation.
- I'd like to go trough xml document, all of its nodes
- Check the node for attribute existence
Case if node doesn't have attribute, get/generate String with value of its xpath
Case if node does have attributes, iterate trough attribute list and create xpath for each attribute including the node as well.
Word of advice? Hopefully you will provide some useful intel
EDIT:
Reason for doing this is .. I'm writing automated tests in jmeter, so for every request I need to verify that request actually did its job so I'm asserting results by getting nodes values with xpath.(extra info - irrelevant)
When the request is small its not problem to create asserts by hand, but for larger ones its a really pain in the .. (extra info - irrelevant)
BOUNTY :
I'm looking for java approach
Goal
My goal is to achieve following from this ex xml file :
<root>
<elemA>one</elemA>
<elemA attribute1='first' attribute2='second'>two</elemA>
<elemB>three</elemB>
<elemA>four</elemA>
<elemC>
<elemB>five</elemB>
</elemC>
</root>
to produce the following :
//root[1]/elemA[1]='one'
//root[1]/elemA[2]='two'
//root[1]/elemA[2][@attribute1='first']
//root[1]/elemA[2][@attribute2='second']
//root[1]/elemB[1]='three'
//root[1]/elemA[3]='four'
//root[1]/elemC[1]/elemB[1]='five'
Explained :
- If node value/text is not null/zero, get xpath , add = 'nodevalue' for assertion purpose
- If node has attributes create assert for them too
BOUNTY UPDATE :
I found this example, it doesn't produce the correct results , but I'm looking something like this:
I did the exact same thing last week for processing my xml to solr compliant format.
Since you wanted a pseudo code: This is how I accomplished that.
// You can skip the reference to parent and child.
1_ Initialize a custom node object: NodeObjectVO {String nodeName, String path, List attr, NodeObjectVO parent, List child}
2_ Create an empty list
3_ Create a dom representation of xml and iterate thro the node. For each node, get the corresponding information. All the information like Node name,attribute names and value should be readily available from dom object. ( You need to check the dom NodeType, code should ignore processing instruction and plain text nodes.)
// Code Bloat warning. 4_ The only tricky part is get path. I created an iterative utility method to get the xpath string from NodeElement. (While(node.Parent != null ) { path+=node.parent.nodeName}.
(You can also achieve this by maintaining a global path variable, that keeps track of the parent path for each iteration.)
5_ In the setter method of setAttributes (List), I will append the object's path with all the available attributes. (one path with all available attributes. Not a list of path with each possible combination of attributes. You might want to do someother way. )
6_ Add the NodeObjectVO to the list.
7_ Now we have a flat (not hierrarchial) list of custom Node Objects, that have all the information I need.
(Note: Like I mentioned, I maintain parent child relationship, you should probably skip that part. There is a possibility of code bloating, especially while getparentpath. For small xml this was not a problem, but this is a concern for large xml).
I've done a similar task once. The main idea used was that you can use indexes of the element in the xpath. For example in the following xml
xpath to the second
<el/>
will be/root[1]/el[2]
(xpath indexes are 1-based). This reads as "take the first root, then take the second one from all elements with the name el". So elementsomething
does not affect indexing of elementsel
. So you can in theory create an xpath for each specific element in your xml. In practice I've accomplished this by walking the tree recursevely and remembering information about elements and their indexes along the way.Creating xpath referencing specific attribute of the element then was just adding '/@attrName' to element's xpath.