XPATH readout - HAshmap/Array or Enum
Hi,
I am reading this from my xml file:
<Taxes>
<Tax TaxCode="code1" Amount="500.00"/>
<Tax TaxCode="code2" Amount="100.00"/>
<Tax TaxCode="code3" Amount="100.00"/>
<Tax TaxCode="code4" Amount="1000.00"/>
<Tax TaxCode="code5" Amount="2000.00"/>
</Taxes>
and am passing the Taxcodes as keys and the Amounts as values into a HashMap.
My Problem is, if there are more than 3 TaxCodes, i have to return the amounts of the "extra" Taxcodes as a summed value and forget about the other taxcodes. Thus leaving me with:
<Tax TaxCode="code1" Amount="500.00"/>
<Tax TaxCode="code2" Amount="100.00"/>
<Tax TaxCode="code3" Amount="3100.00"/>
Is Hashmap the way to go here - or is there an easier way?
[1239 byte] By [
adunkey10a] at [2007-11-26 17:39:32]

When do you have to combine them. (When your loading them?) I would suggest having a class that would combine things for you. But have an interface similar to HashMap, and could output a hashmap when all the codes were loaded.
I combine them bfore I send them to the server, i'm trying to do something like:
HashMap map = getTaxAmounts(".xml");
if( map.size() > 3) {
HashMap newMap = new HashMap();
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
// Get key
Object key = it.next();
}
it = map.values().iterator();
while (it.hasNext()) {
// Get value
Object value = it.next();
}
}
else {
System.err.println("do nothing");
System.err.println("Original map == "+map.size());
}
how do I do the calculation to get the first 3 Objects and the summation of any keys not in size > 3 into the final key value?
Thanks
> how do I do the calculation to get the first 3
> Objects and the summation of any keys not in size > 3
> into the final key value?
That code looks strange.Not sure what it means, but I think I understand your goal.
Like I said I would create a new class that would handle the logic of this business rule. And when you load the xml you would just pass the tax codes and it would take care of combining the last values and outputting a map.
I'm sorry I don't understand what you mean at all - I load the xml from this method:
public static HashMap getTaxAmounts(String xml) throws Exception {
HashMap taxes = new HashMap();
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(xml);
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
// this exp should ge the TaxCode
XPathExpression expr = xpath.compile("//Tax/@TaxCode");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
// this exp should get the Amount
XPathExpression expr1 = xpath.compile("//Tax/@Amount");
Object result1 = expr1.evaluate(doc, XPathConstants.NODESET);
NodeList nodes1 = (NodeList) result1;
// combine the 2 nodeLists into a HashMap
for (int i = 0; i < nodes1.getLength(); i++) {
taxes.put( nodes.item(i).getNodeValue(), nodes1.item(i).getNodeValue());
}
return taxes;
}
probably not the best code that you have ever seen, then in the main() I'm trying to create a new HashMap of size 3 & put the first keys and values(last one summed) into it. but i can't find a method in HashMap & that's why I wondering if a 2-D array or enumeration would be easier?
here's what I have already:
public static void main(String[] args) {
try {
HashMap map = getTaxAmounts("RQ.xml");
if( map.size() > 3) {
System.err.println("More than 3 Tax elements");
HashMap newMap = new HashMap();
Iterator it1 = map.keySet().iterator();
int i = 0;
while ( it1.hasNext() && i < 3) {
Object key = it.next();
newMap.put(key, 0);
i++;
}
...
is that any help?
should I restart?
Thanks
I didn't realize the program was so small. Also are you using something older than 1.5? Because I don't see any enhanced for loops.Anyway, do you know how to create new classes? Because based on the code you have seen it looks like you are doing everything in a procedural manner.
it's only part of a program, which is pretty small alright. i am using 1.5 too; I know how to create new classes but am not sure if the functionality I am using is correct as I can't seem to make the second HashMap easily - am I right in doing so with HashMaps or should I use some other structure that would be easier to loop with?
Basically, I know a bit of programming, but as you can see, not much!
I just need some guidance on how to write this properly - is my first method - getTaxAmounts() any good even? as it doesn't even structure the values properly i.e. it should come out as:
"code1" <=>500.00
"code2"<=>100.00
"code3"<=>100.00
"code4"<=>"1000.00"
"code5"<=>"2000.00"
it comes out in the order code2, code4, code5, code1, code3.
this is very strange!
I'm glad of all your help but think i need help from the bottom up if you have the time.
Thanks
One simple suggestion now that a look closer at your code is to sum the values before you add them.
Where you have:
// combine the 2 nodeLists into a HashMap
for (int i = 0; i < nodes1.getLength(); i++) {
taxes.put( nodes.item(i).getNodeValue(), nodes1.item(i).getNodeValue());
}
Do something along the lines of
for (int i = 0; i < nodes1.getLength() && (i<2); i++) {
taxes.put( nodes.item(i).getNodeValue(), nodes1.item(i).getNodeValue());
}
if(nodes1.getLength() >=3){
int total = 0;
for (int i = 2; i < nodes1.getLength(); i++) {
total += nodes1.item(i).getNodeValue());
}
taxes.put( nodes.item(3).getNodeValue(), total);
}
*Note I hardcoded the limit on number of the codes (you might want to replace it), also you will need to convert the node values to numbers in order to sum them.
Hi,
thanks for all your help so far - it makes more sense!
I now have another problem with the remove in the HashMao; What I'm trying to do is: given an xml like:
<Taxes>
<Tax TaxCode="code1" Amount="500.00"/>
<Tax TaxCode="code2" Amount="100.00"/>
<Tax TaxCode="code3" Amount="300.00"/>
<Tax TaxCode="code4" Amount="1000.00"/>
<Tax TaxCode="code5" Amount="10000.00"/>
<Tax TaxCode="XF" Amount="4000.00"/>
<Tax TaxCode="ZP" Amount="6000.00"/>
</Taxes>
for the scencrio when there are more than 3 TaxCode - the code has to change to "XT" - this I have working. However if the tax codes "XF" and "ZF" exist - they should be deleted - I'm trying to do it with what's below, but it's not working:
String seq = "XF";
String seq1 = "ZP";
for ( int i = 0; i < nodes.getLength(); i++) {
if( (nodes.item(i).toString().contains(seq))||
(nodes.item(i).toString().contains(seq1))) {
//delete this key/value
taxes.remove(nodes.item(i).getNodeValue());
taxes.remove(nodes1.item(i).getNodeValue());
}
}
for ( int i = 0; i < nodes1.getLength() && (i<2); i++) {
taxes.put( nodes.item(i).getNodeValue(), nodes1.item(i).getNodeValue());
}
if( nodes1.getLength() >= 3){
float total = 0.00f;
for ( int i = 2; i < nodes1.getLength(); i++) {
total += Float.parseFloat(nodes1.item(i).getNodeValue());
}
String xt = nodes.item(2).getNodeValue();
xt = "XT";
taxes.put( xt, total);
}
return taxes;
actually, this seems to work - I'll just have to modify it for when there is less than 3 tax elements & one has an XF.
if( nodes1.getLength() >= 3){
float total = 0.00f;
for ( int i = 2; i < nodes1.getLength(); i++) {
total += Float.parseFloat(nodes1.item(i).getNodeValue());
}
String xt = nodes.item(2).getNodeValue();
xt = "XT";
String seq = "XF";
String seq1 = "ZP";
for ( int i = 0; i < nodes.getLength(); i++) {
if( (nodes.item(i).toString().contains(seq))||
(nodes.item(i).toString().contains(seq1))) {
//delete this key/value
taxes.remove(nodes.item(i).getNodeValue().toString());
taxes.remove(nodes1.item(i).getNodeValue().toString());
total -= Float.parseFloat(nodes1.item(i).getNodeValue());
taxes.put( xt, total);
}
}