View Category
Process an XML document
Given the XML Document:
<shopping>
<item name=
<item name=
</shopping>
Print out the total cost of the items, e.g. $14.50
<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
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
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
clojure
(println (format "Total cost of items are $%#.2f"
(->> (xml-seq (parse *xml-input-stream*))
(filter #(= :item (:tag %))) ; Remove all but the item tags
(map :attrs) ; Keep the attributes
(map (fn [e] (str "(* " (:quantity e) " " (:price e) ")"))) ; Get the total price as a sexp
(map read-string) ; "(* quantity price)" -> (* quantity price)
(map eval) ; (* quantity price) -> quantity*price
(apply +)))) ; Sum all elements
(->> (xml-seq (parse *xml-input-stream*))
(filter #(= :item (:tag %))) ; Remove all but the item tags
(map :attrs) ; Keep the attributes
(map (fn [e] (str "(* " (:quantity e) " " (:price e) ")"))) ; Get the total price as a sexp
(map read-string) ; "(* quantity price)" -> (* quantity price)
(map eval) ; (* quantity price) -> quantity*price
(apply +)))) ; Sum all elements
fsharp
#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
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
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)
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)
// 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"
// 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"
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")
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")
groovy
printf '$%.2f\n', new XmlSlurper().parseText(xml).item.collect{
it.@quantity.toInteger() * it.@price.toFloat()
}.sum()
it.@quantity.toInteger() * it.@price.toFloat()
}.sum()
java
// 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();
}
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();
}
erlang
-include_lib("xmerl/include/xmerl.hrl").
-export([get_total/1]).
get_total(ShoppingList) ->
{XmlElt, _} = xmerl_scan:string(ShoppingList),
Items = xmerl_xpath:string("/shopping/item", XmlElt),
Total = lists:foldl(fun(Item, Tot) ->
[#xmlAttribute{value = PriceString}] = xmerl_xpath:string("/item/@price", Item),
{Price, _} = string:to_float(PriceString),
[#xmlAttribute{value = QuantityString}] = xmerl_xpath:string("/item/@quantity", Item),
{Quantity, _} = string:to_integer(QuantityString),
Tot + Price*Quantity
end,
0, Items),
io:format("$~.2f~n", [Total]).
-export([get_total/1]).
get_total(ShoppingList) ->
{XmlElt, _} = xmerl_scan:string(ShoppingList),
Items = xmerl_xpath:string("/shopping/item", XmlElt),
Total = lists:foldl(fun(Item, Tot) ->
[#xmlAttribute{value = PriceString}] = xmerl_xpath:string("/item/@price", Item),
{Price, _} = string:to_float(PriceString),
[#xmlAttribute{value = QuantityString}] = xmerl_xpath:string("/item/@quantity", Item),
{Quantity, _} = string:to_integer(QuantityString),
Tot + Price*Quantity
end,
0, Items),
io:format("$~.2f~n", [Total]).
perl
#! /usr/bin/perl
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# 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
my $xml =
" <shopping>\n"
." <item name=\"bread\" quantity=\"3\" price=\"2.50\"/>\n"
." <item name=\"milk\" quantity=\"2\" price=\"3.50\"/>\n"
." </shopping>\n";
my $xs = XML::Simple->new();
my $ref = $xs->XMLin($xml);
my $stuff = ${$ref}{item};
my $q;
my $p;
my $t;
my $z;
foreach my $item ( sort keys %{$stuff}){
$q = ${$stuff}{$item}{quantity};
$p = ${$stuff}{$item}{price};
$z = $q*$p;
printf "%5.5s %2d @\$%5.2f = \$%5.2f\n",$item,$q,$p,$z;
$t += $z;
}
printf "Total \$%5.2f\n",$t;
#eos
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# 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
my $xml =
" <shopping>\n"
." <item name=\"bread\" quantity=\"3\" price=\"2.50\"/>\n"
." <item name=\"milk\" quantity=\"2\" price=\"3.50\"/>\n"
." </shopping>\n";
my $xs = XML::Simple->new();
my $ref = $xs->XMLin($xml);
my $stuff = ${$ref}{item};
my $q;
my $p;
my $t;
my $z;
foreach my $item ( sort keys %{$stuff}){
$q = ${$stuff}{$item}{quantity};
$p = ${$stuff}{$item}{price};
$z = $q*$p;
printf "%5.5s %2d @\$%5.2f = \$%5.2f\n",$item,$q,$p,$z;
$t += $z;
}
printf "Total \$%5.2f\n",$t;
#eos
use strict;
use XML::Twig;
use Data::Dumper;
my $xml = <<ENDXML;
<shopping>
<item name="bread" quantity="3" price="2.50"/>
<item name="milk" quantity="2" price="3.50"/>
</shopping>
ENDXML
my $xt = XML::Twig->parse( $xml );
my $price;
foreach my $item ($xt->root->children('item')) {
$price += ($item->{att}{price} * $item->{att}{quantity})
}
printf "Total Cost: %.2f\n", $price
use XML::Twig;
use Data::Dumper;
my $xml = <<ENDXML;
<shopping>
<item name="bread" quantity="3" price="2.50"/>
<item name="milk" quantity="2" price="3.50"/>
</shopping>
ENDXML
my $xt = XML::Twig->parse( $xml );
my $price;
foreach my $item ($xt->root->children('item')) {
$price += ($item->{att}{price} * $item->{att}{quantity})
}
printf "Total Cost: %.2f\n", $price
create some XML programmatically
Given the following CSV:
bread,3,2.50
milk,2,3.50
Produce the equivalent information in XML, e.g.:
<shopping>
<item name=
<item name=
</shopping>
bread,3,2.50
milk,2,3.50
Produce the equivalent information in XML, e.g.:
<shopping>
<item name=
"bread" quantity="3" price="2.50" />
<item name=
"milk" quantity="2" price="3.50" />
</shopping>
python
from xml.dom import minidom
csv = """bread,3,2.50
milk,2,3.50"""
doc = minidom.Document()
shopping = doc.createElement("shopping")
for line in csv.split("\n"):
name, quantity, price = line.split(",")
el = doc.createElement("item")
el.setAttribute("name", name)
el.setAttribute("quantity", quantity)
el.setAttribute("price", price)
shopping.appendChild(el)
print shopping.toprettyxml()
csv = """bread,3,2.50
milk,2,3.50"""
doc = minidom.Document()
shopping = doc.createElement("shopping")
for line in csv.split("\n"):
name, quantity, price = line.split(",")
el = doc.createElement("item")
el.setAttribute("name", name)
el.setAttribute("quantity", quantity)
el.setAttribute("price", price)
shopping.appendChild(el)
print shopping.toprettyxml()
from xml.etree.ElementTree import Element, SubElement, tostring
csv = """bread,3,2.50
milk,2,3.50"""
root = Element('shopping')
for line in csv.split("\n"):
name, quantity, price = line.split(",")
SubElement(root,'item', {'name' : name,
'quantity' : quantity,
'price' : price })
print tostring(root)
csv = """bread,3,2.50
milk,2,3.50"""
root = Element('shopping')
for line in csv.split("\n"):
name, quantity, price = line.split(",")
SubElement(root,'item', {'name' : name,
'quantity' : quantity,
'price' : price })
print tostring(root)
clojure
(defn list->xml-item [lst]
(let [[name quantity price] (map str lst)]
{:tag :item
:attrs {:name name
:quantity quantity
:price price}}))
(defn cvs->xml [r]
(->> (map #(read-string (str "(" % ")")) (line-seq r))
(map list->xml-item)
(assoc {:tag :shopping} :content)
(emit)
(with-out-str)))
(println (cvs->xml *cvs-reader*))
(let [[name quantity price] (map str lst)]
{:tag :item
:attrs {:name name
:quantity quantity
:price price}}))
(defn cvs->xml [r]
(->> (map #(read-string (str "(" % ")")) (line-seq r))
(map list->xml-item)
(assoc {:tag :shopping} :content)
(emit)
(with-out-str)))
(println (cvs->xml *cvs-reader*))
fsharp
#r "System.Xml.dll"
#r "System.Xml.Linq.dll"
open System
open System.Xml
open System.Xml.Linq
let data = "bread,3,2.50
milk,2,3.50"
let X name =
XName.Get(name)
let lines = data.Split( [|"\n" |], StringSplitOptions.RemoveEmptyEntries)
let document = new XDocument()
let element = new XElement(X "shopping")
document.Add(element)
lines
|> Seq.iter (fun line ->
let items = line.Split([|','|])
let item = new XElement(X "item",
new XAttribute(X "name", items.[0]),
new XAttribute(X "quantity", items.[1]),
new XAttribute(X "price", items.[2]))
element.Add(item))
let output = document.ToString();;
#r "System.Xml.Linq.dll"
open System
open System.Xml
open System.Xml.Linq
let data = "bread,3,2.50
milk,2,3.50"
let X name =
XName.Get(name)
let lines = data.Split( [|"\n" |], StringSplitOptions.RemoveEmptyEntries)
let document = new XDocument()
let element = new XElement(X "shopping")
document.Add(element)
lines
|> Seq.iter (fun line ->
let items = line.Split([|','|])
let item = new XElement(X "item",
new XAttribute(X "name", items.[0]),
new XAttribute(X "quantity", items.[1]),
new XAttribute(X "price", items.[2]))
element.Add(item))
let output = document.ToString();;
fantom
sum := 0.0
rows := CsvInStream(File(`shop.csv`).in).readAllRows
doc := XDoc()
doc.root = XElem("shopping")
{
root := it
rows.each |Str[] row|
{
root.add(XElem("item")
{
XAttr("name", row[0]),
XAttr("quantity", row[1]),
XAttr("price", row[2])
})
}
}
os := File(`shop.xml`).out
doc.write(os)
os.close
rows := CsvInStream(File(`shop.csv`).in).readAllRows
doc := XDoc()
doc.root = XElem("shopping")
{
root := it
rows.each |Str[] row|
{
root.add(XElem("item")
{
XAttr("name", row[0]),
XAttr("quantity", row[1]),
XAttr("price", row[2])
})
}
}
os := File(`shop.xml`).out
doc.write(os)
os.close
groovy
b = new groovy.xml.MarkupBuilder()
b.shopping {
csv.eachLine { line ->
(n, q, p) = line.split(',')
item(name:n, quantity:q, price:p)
}
}
b.shopping {
csv.eachLine { line ->
(n, q, p) = line.split(',')
item(name:n, quantity:q, price:p)
}
}
// Groovy equivalent of Java JAXB solution
@XmlAccessorType(NONE)
class Item {
@XmlAttribute String name
@XmlAttribute Integer quantity
@XmlAttribute Double price
}
@XmlAccessorType(NONE)
@XmlRootElement
class Shopping {
@XmlElement Set<Item> items = []
}
Shopping shopping = new Shopping()
csvtext.eachLine{ line ->
(n, q, p) = line.split(',')
shopping.items << new Item(name:n, quantity:q.toInteger(), price:p.toDouble())
}
JAXB.marshal shopping, System.out
@XmlAccessorType(NONE)
class Item {
@XmlAttribute String name
@XmlAttribute Integer quantity
@XmlAttribute Double price
}
@XmlAccessorType(NONE)
@XmlRootElement
class Shopping {
@XmlElement Set<Item> items = []
}
Shopping shopping = new Shopping()
csvtext.eachLine{ line ->
(n, q, p) = line.split(',')
shopping.items << new Item(name:n, quantity:q.toInteger(), price:p.toDouble())
}
JAXB.marshal shopping, System.out
java
// In this solution JAXB is used to created the xml output.
// JAXB is included in Java 1.6. Runs with 1.5 if you include JAXB Jars
// in the classpath.
class Item {
// Of course you use getters and setters and declare attributes private.
// In this sample a "dirty" way is chosen to keep LOC low.
@XmlAttribute
String name;
@XmlAttribute
Integer quantity;
@XmlAttribute
Double price;
}
@XmlRootElement
class Shopping {
@XmlElement
Set<Item> items = new HashSet<Item>();
}
String line = null;
Shopping shopping = new Shopping();
try {
BufferedReader reader = new BufferedReader(new FileReader("shopping.csv"));
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
Item item = new Item();
item.name = parts[0];
item.quantity = Integer.parseInt(parts[1]);
item.price = Double.parseDouble(parts[2]);
shopping.items.add(item);
}
JAXB.marshal(shopping, "D:" + File.separatorChar + "shopping.auto.xml");
} catch (IOException e) {
e.printStackTrace();
}
// JAXB is included in Java 1.6. Runs with 1.5 if you include JAXB Jars
// in the classpath.
class Item {
// Of course you use getters and setters and declare attributes private.
// In this sample a "dirty" way is chosen to keep LOC low.
@XmlAttribute
String name;
@XmlAttribute
Integer quantity;
@XmlAttribute
Double price;
}
@XmlRootElement
class Shopping {
@XmlElement
Set<Item> items = new HashSet<Item>();
}
String line = null;
Shopping shopping = new Shopping();
try {
BufferedReader reader = new BufferedReader(new FileReader("shopping.csv"));
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
Item item = new Item();
item.name = parts[0];
item.quantity = Integer.parseInt(parts[1]);
item.price = Double.parseDouble(parts[2]);
shopping.items.add(item);
}
JAXB.marshal(shopping, "D:" + File.separatorChar + "shopping.auto.xml");
} catch (IOException e) {
e.printStackTrace();
}
erlang
to_xml(ShoppingList) ->
Items = lists:map(fun(L) ->
[Name, Quantity, Price] = string:tokens(L, ","),
{item, [{name, Name}, {quantity, Quantity}, {price, Price}], []}
end, string:tokens(ShoppingList, "\n")),
xmerl:export_simple([{shopping, [], Items}], xmerl_xml).
Items = lists:map(fun(L) ->
[Name, Quantity, Price] = string:tokens(L, ","),
{item, [{name, Name}, {quantity, Quantity}, {price, Price}], []}
end, string:tokens(ShoppingList, "\n")),
xmerl:export_simple([{shopping, [], Items}], xmerl_xml).
perl
#! /usr/bin/perl
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# bread,3,2.50
# milk,2,3.50
#
# Produce the equivalent information in XML, e.g.:
#
# <shopping>
# <item name="bread" quantity="3" price="2.50" />
# <item name="milk" quantity="2" price="3.50" />
# </shopping>
#
my $line;
my $item;
my $q;
my $p;
my $z;
my $xs = XML::Simple->new();
my %d = ();
while($line=<DATA>){
chomp $line;
($item,$q,$p) = split ",",$line;
$d{shopping}{item}{$item}{quantity} = $q;
$d{shopping}{item}{$item}{price} = $p;
}
$xml = $xs->XMLout(\%d, KeepRoot => 1);
print $xml,"\n";
__DATA__
bread,3,2.50
milk,2,3.50
# -*- Mode: CPerl -*-
use strict;
use XML::Simple;
use Data::Dumper;
# bread,3,2.50
# milk,2,3.50
#
# Produce the equivalent information in XML, e.g.:
#
# <shopping>
# <item name="bread" quantity="3" price="2.50" />
# <item name="milk" quantity="2" price="3.50" />
# </shopping>
#
my $line;
my $item;
my $q;
my $p;
my $z;
my $xs = XML::Simple->new();
my %d = ();
while($line=<DATA>){
chomp $line;
($item,$q,$p) = split ",",$line;
$d{shopping}{item}{$item}{quantity} = $q;
$d{shopping}{item}{$item}{price} = $p;
}
$xml = $xs->XMLout(\%d, KeepRoot => 1);
print $xml,"\n";
__DATA__
bread,3,2.50
milk,2,3.50
use strict;
use XML::Writer;
use Text::CSV;
my $csv = <<ENDOFCSV;
bread,3,2.50
milk,2,3.50
ENDOFCSV
open my $fh, '<', \$csv or die "Can't open string, $!\n";
my $csv = Text::CSV->new;
my $writer = XML::Writer->new(DATA_MODE => 1, DATA_INDENT => 2);
$writer->startTag('shopping');
while (my $arr_ref = $csv->getline($fh)) {
my %attributes;
@attributes{qw/name quantity price/} =
@{$arr_ref}[0..2];
$writer->emptyTag('item' => %attributes)
}
$writer->endTag('shopping');
use XML::Writer;
use Text::CSV;
my $csv = <<ENDOFCSV;
bread,3,2.50
milk,2,3.50
ENDOFCSV
open my $fh, '<', \$csv or die "Can't open string, $!\n";
my $csv = Text::CSV->new;
my $writer = XML::Writer->new(DATA_MODE => 1, DATA_INDENT => 2);
$writer->startTag('shopping');
while (my $arr_ref = $csv->getline($fh)) {
my %attributes;
@attributes{qw/name quantity price/} =
@{$arr_ref}[0..2];
$writer->emptyTag('item' => %attributes)
}
$writer->endTag('shopping');
