AutoPilot searchProperties = new AutoPilot();
searchProperties.selectXPath("/BatchItemSearchResultAnswer/Result/SearchProperties/Content/Item");
searchProperties.bind(nav);
searchPro searchOption = new searchPro();
while (searchProperties.evalXPath() != -1) {
//reuser
name.resetXPath();
name.selectXPath("Name");
searchOption.id = Id.evalXPathToString();
searchOption.name = name.evalXPathToString();
Log.e("SearchId", Id.evalXPathToString());
Log.e("SearchName", name.evalXPathToString());
Image.resetXPath();
Image.selectXPath("/BatchItemSearchResultAnswer/Result/SearchProperties/Content/Item/Values/PropertyValue");
searchOption.propertyList = new ArrayList();
while (Image.evalXPath() != -1) {
property pro = new Property();
pro.id = Id.evalXPathToString();
Log.e("SearchPId", Id.evalXPathToString());
Log.e("SearchPName", name.evalXPathToString());
searchOption.propertyList.add(pro);
}
}
here is my XML
<SearchProperties><Content> <Item><Id>12345</Id><Name>scene</Name><Values><PropertyValue><Id>29</Id><Name>Le</Name></PropertyValue> <PropertyValue><Id>208</Id><Name>Business</Name></PropertyValue> </Values></Item><Item>..</Item></Content></SearchProperties>
SearchProperties while loop only one time . when i remove Image.selectPath("") line. that time it will loop correctly. how to solve this.
Thanks in Advance.
You are nesting XPath evaluations... it is always better to move XPath selection out of a while loop whenever possible. The reason is that compile XPath is relatively speaking a slow operation... as it needs to construct XPath data structure, perform various optimization that speeds up xpath evaluation...
Manual navigation might be more efficient in your use case as you have indicated that you want to loop over XML tree only once...
Also you nested one absolute XPath inside another related absolute XPath, it is very bad for performance, and does not really make sense... I changed the image object's xpath binding to a relative xpath "values/propertyValue
."
The overall goal is to reduced wasteful computation and maximize reuse. Concerning XPath reuse, as you are aware there are 4 methods for XPath evaluation... evalXPath()
, evalXPathToString()
, evalXPathToBoolean()
, evalXPathToNumber()
. Of those 4 methods, only evalXPath() requires resetXPath() for subsequent reuse... other 3 call resetXPath internally..and thus do not require you to call resetXPath() after each invocation.
AutoPilot searchProperties = new AutoPilot();
AutoPilot image = new AutoPilot(vn);
AutoPilot name = new AutoPilot(vn);
name.selectXPath("Name");
Image.selectXPath("values/PropertyValue");// should use relative path here, makes a huge difference in performance
searchProperties.selectXPath("/BatchItemSearchResultAnswer/Result/SearchProperties/Content/Item");
searchProperties.bind(nav);
searchPro searchOption = new searchPro();
while (searchProperties.evalXPath() != -1) {
//reuser
//name.resetXPath();
searchOption.id = Id.evalXPathToString();
searchOption.name = name.evalXPathToString();
Log.e("SearchId", Id.evalXPathToString());
Log.e("SearchName", name.evalXPathToString());
searchOption.propertyList = new ArrayList();
vn.push()
while (Image.evalXPath() != -1) {
property pro = new Property();
pro.id = Id.evalXPathToString();
Log.e("SearchPId", Id.evalXPathToString());
Log.e("SearchPName", name.evalXPathToString());
searchOption.propertyList.add(pro);
}
Image.resetXPath();
vn.pop();
}
Finally spending whole day got the result .
if (navTemp.toElement(VTDNav.FC, "SearchProperties")) {
Log.e("Search", "SearchProperties");
if (navTemp.toElement(VTDNav.FC, "Content")) {
Log.e("Search", "Content");
if (navTemp.toElement(VTDNav.FC, "Item")) {
do {
SearchPropertiesItems item = new SearchPropertiesItems();
if (navTemp.toElement(VTDNav.FC)) {
Log.e("Search", "Item");
do {
if (!navTemp.matchElement("Values")) {
if (navTemp.toString(navTemp.getCurrentIndex()).equalsIgnoreCase("id")) {
item.id = navTemp.toString(navTemp.getText());
} else {
item.name = navTemp.toString(navTemp.getText());
}
//Log.e("SearchItem", navTemp.toString(navTemp.getCurrentIndex()) + "==>" + navTemp.toString(navTemp.getText()));
} else {
//if (navTemp.toElement(VTDNav.FC, "Values")) {
if (navTemp.toElement(VTDNav.FC, "PropertyValue")) {
do {
SearchPropertiesProperty property = new SearchPropertiesProperty();
if (navTemp.toElement(VTDNav.FC)) {
do {
if (navTemp.toString(navTemp.getCurrentIndex()).equalsIgnoreCase("id")) {
property.id = navTemp.toString(navTemp.getText());
} else {
property.name = navTemp.toString(navTemp.getText());
}
// Log.e("SearchItem >>", navTemp.toString(navTemp.getCurrentIndex()) + "==>" + navTemp.toString(navTemp.getText()));
}
while (navTemp.toElement(VTDNav.NEXT_SIBLING));
navTemp.toElement(VTDNav.P);
property.ItemId = item.id;
item.properties.add(property);
}
}
while (navTemp.toElement(VTDNav.NEXT_SIBLING));
navTemp.toElement(VTDNav.P);
}
// }
}
} while (navTemp.toElement(VTDNav.NEXT_SIBLING));
navTemp.toElement(VTDNav.P);
productList.searchPropertiesItems.add(item);
}
} while (navTemp.toElement(VTDNav.NEXT_SIBLING));
}
}
}
Reference links : http://vtd-xml.sourceforge.net/codeSample/cs5.html http://www.javaworld.com/article/2071745/soa/simplify-xml-processing-with-vtd-xml.html
来源:https://stackoverflow.com/questions/36711266/how-to-get-inner-array-child-element-in-xml-using-ximpleware