View Problem
XML

Process an XML document

Given the XML Document:

<shopping>
  <item name="bread" quantity="3" price="2.50"/>
  <item name="milk" quantity="2" price="3.50"/>
</shopping>

Print out the total cost of the items, e.g. $14.50
DiskEdit
python
from xml.dom.minidom import parseString
document = parseString(
"""<shopping>
<item name="bread" quantity="3" price="2.50"/>
<item name="milk" quantity="2" price="3.50"/>
</shopping>""").documentElement
total = sum([float(item.getAttribute('price')) *
int(item.getAttribute('quantity'))
for item in document.getElementsByTagName('item')])
print '$%.2f' % total
DiskEdit
csharp
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(
@"<shopping>
<item name='bread' quantity='3' price='2.50'/>
<item name='milk' quantity='2' price='3.50'/>
</shopping>");

string decimalSeparator= System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;

double sum=0;

foreach(System.Xml.XmlNode nodo in doc.SelectNodes("/shopping/item")){
sum += int.Parse(nodo.Attributes["quantity"].InnerText) * double.Parse(nodo.Attributes["price"].InnerText.Replace(".",decimalSeparator));
}
Console.WriteLine("{0:#.00}",sum);
ExpandDiskEdit
java >= 1.5
// solution uses JAXP and SAX included in Java API since version >= 1.5
class ShoppingContentHandler extends DefaultHandler {
Double priceSum = 0d;
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
if(name.equals("item")) {
String quantityString = attributes.getValue(attributes.getIndex("quantity"));
String priceString = attributes.getValue(attributes.getIndex("price"));
Integer quantity = Integer.parseInt(quantityString);
Double price = Double.parseDouble(priceString);
priceSum += (quantity * price);
}
}
public Double getPriceSum() {
return priceSum;
}
}

SAXParserFactory parserFactory = SAXParserFactory.newInstance();
try {
SAXParser parser = parserFactory.newSAXParser();
XMLReader reader = parser.getXMLReader();
ShoppingContentHandler contentHandler = new ShoppingContentHandler();
reader.setContentHandler(contentHandler);
reader.parse(new InputSource(new FileReader("shopping.xml")));
System.out.printf("$%.2f", contentHandler.getPriceSum());

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ExpandDiskEdit
fantom
sum := 0.0
root := XParser(File(`shop.xml`).in).parseDoc.root
if (root.name == "shopping")
{
root.elems.each
{
if (it.name == "item")
{
quantity := Int.fromStr(it.get("quantity"))
price := Decimal.fromStr(it.get("price"))
sum += quantity * price;
}
}
}
echo("\$$sum")
DiskEdit
fsharp F# 2.0 Interactive build 4.0.30319.1
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll"

open System
open System.Xml.Linq
//XElement Helper
let xname sname = XName.Get sname

let xmlsnippet =
let snippet = new XElement(xname "shopping")
//create bread
let bread = new XElement(xname "item")
bread.SetAttributeValue(xname "name","bread")
bread.SetAttributeValue(xname "quantity",3)
bread.SetAttributeValue(xname "price",2.50)
//add bread to snippet
snippet.Add(bread)
//create milk
let milk = new XElement(xname "item")
milk.SetAttributeValue(xname "name","milk")
milk.SetAttributeValue(xname "quantity",2)
milk.SetAttributeValue(xname "price",3.50)
//add milk to snippet
snippet.Add(milk)
snippet

let totalprice (xe: XElement) =
xe.Descendants(xname "item")
|> Seq.map(fun i -> Double.Parse(i.Attribute(xname "price").Value))
|> Seq.fold(fun acc x -> acc + x) 0.0


ExpandDiskEdit
fsharp
let xname sname = XName.Get sname
let xattr (elem: XElement) sname = elem.Attribute(xname sname).Value
let xml = XDocument.Load("xml.txt")

let shoppingCost =
xml.Descendants(xname "item")
|> Seq.map (fun i -> Double.Parse(xattr i "quantity"), Double.Parse(xattr i "price"))
|> Seq.sumBy (fun (quantity, price) -> quantity * price)
ExpandDiskEdit
fsharp
// Alternative solution that uses XML Navigation, and XPath expressions to ensure that
// the items have the required attributes
let xname sname = XName.Get sname
let xattr (elem: XElement) sname = elem.Attribute(xname sname).Value

let navigator = XPathDocument("xml.txt").CreateNavigator()
let path = XPathExpression.Compile("/shopping/item[@price][@quantity]")
let names = XmlNamespaceManager(navigator.NameTable)
path.SetContext(names)
let shoppingCost =
match path.ReturnType with
| XPathResultType.NodeSet ->
navigator.Select(path)
|> Seq.cast
|> Seq.map (fun (i: XPathNavigator) ->
if i.IsNode then
let elem = XElement.Parse(i.OuterXml)
Double.Parse(xattr elem "quantity"), Double.Parse(xattr elem "price")
else
failwith "Error in expression, expecting to see a node"
)
|> Seq.sumBy (fun (quantity, price) -> quantity * price)
| _ -> failwith "Error in expression, expecting to see a node set"

Submit a new solution for python, csharp, java, fantom ...
There are 13 other solutions in additional languages (clojure, cpp, erlang, groovy ...)