Write a program that can read XML files, such as <inventory> <products> <product
ID: 3777961 • Letter: W
Question
Write a program that can read XML files, such as
<inventory>
<products>
<product>
<code>012-345</code>
<desc>Cat food desc>
<price>12.45</price>
<quantity>34</quantity>
</product>
<product>
<code>345-678</code>
<desc>Dog food desc>
<price>6.99</price>
<quantity>25</quantity>
</product>
</products>
<transactions>
<purchased>
<code>012-345</code>
<count>100</count>
</purchased>
<sold>
<code>012-345</code>
<count>67</count>
</sold>
<purchased>
<code>345-678</code>
<count>50</count>
</purchased>
<sold>
<code>345-678</code>
<count>25</sold>
</sold>
</transactions>
</bank>
Your program should construct an InventoryParser object, parse the XML data & create new Product objects in the InventoryParser for each of the products the XML data, execute all of the transactions from the file, and print the list of products & total value of the inventory. Note that there can be any number of products, and any number of purchased and sold transactions. Do not hard-code a specific number of products or transactions.
Download and use the provided InventoryParserDemo.java class as the main program for your solution, and download the provided InventoryParser.java and Product.java classes to use with yourInventoryParserDemo solution. Complete the parse() method in the InventoryParser to finish the program. Download and use the provided inventory.xml to test your program – after the transactions, the products from the provided inventory.xml file should have the results:
016-023 Gallon 2% Milk 15 2.49
016-043 Saltine Crackers 20 1.49
019-011 Paper Towels 12 2.23 [corrected from 18 on Nov 26]
020-026 1 Qt. 10W-40 Motor Oil 28 5.99
Total value of inventory: 261.63
(Different numbers of products and transactions will be used to test your program, so don’t assume there are only four products in the XML data.)
To run the InventoryParserDemo Java program in Eclipse, create a new project, copy the InventoryParserDemo.java, InventoryParser.java, and Product.java files into the src folder of your project, and copy the inventory.xml file into the project's folder.
Explanation / Answer
inventory.xml
<?xml version="1.0"?>
<inventory>
<products>
<product>
<code>016-023</code>
<desc>Gallon 2% Milk</desc>
<quantity>10</quantity>
<price>2.49</price>
</product>
<product>
<code>016-043</code>
<desc>Saltine Crackers</desc>
<quantity>20</quantity>
<price>1.49</price>
</product>
<product>
<code>019-011</code>
<desc>Paper Towels</desc>
<quantity>15</quantity>
<price>2.23</price>
</product>
<product>
<code>020-026</code>
<desc>1 Qt. 10W-40 Motor Oil</desc>
<quantity>28</quantity>
<price>5.99</price>
</product>
</products>
<transactions>
<purchased>
<code>016-023</code>
<count>5</count>
</purchased>
<sold>
<code>019-011</code>
<count>3</count>
</sold>
</transactions>
</inventory>
InventoryParserDemo.java
import java.util.Scanner;
public class InventoryParserDemo {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(System.in);
InventoryParser inventory = new InventoryParser();
System.out.print("Enter name of the inventory XML file: ");
String filename = in.nextLine();
inventory.parse(filename);
System.out.println("Products: " + inventory.toString());
in.close();
}
}
InventoryParser.java
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/**
* An XML parser for product inventory.
*/
public class InventoryParser {
private ArrayList<Product> products;
private DocumentBuilder builder;
private XPath path;
/**
* Constructs a parser that can parse products in inventory, and initializes
* the list of products in our inventory.
*/
public InventoryParser() throws ParserConfigurationException {
products = new ArrayList<Product>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
builder = factory.newDocumentBuilder();
XPathFactory xpfactory = XPathFactory.newInstance();
path = xpfactory.newXPath();
}
/**
* Adds a product to inventory.
*
* @param p
* the product to add
*/
public void addProduct(Product p) {
products.add(p);
}
public Product find(String productCode) {
for (Product p : products) {
if (p.getCode().equals(productCode)) // Found a match
return p;
}
// No match in the entire array list
throw new IllegalArgumentException("Product " + productCode + " was not found");
}
public String toString() {
double totalValue = 0.0;
StringBuffer sb = new StringBuffer();
for (Product p : products) {
sb.append(p.toString());
sb.append(' ');
totalValue += p.getTotalValue();
}
sb.append(String.format("Total value of inventory: %.2f ", totalValue));
return sb.toString();
}
/**
* Parses an XML file containing the inventory of products.
*
* @param fileName
* the name of the file
*/
public void parse(String fileName) throws SAXException, IOException, XPathExpressionException {
File f = new File(fileName);
Document doc = builder.parse(f);
int prodCount = Integer.parseInt(path.evaluate("count(inventory/products)", doc));
for (int i = 1; i <= prodCount; i++) {
String code = path.evaluate("/inventory/products[" + i + "]/product/code", doc);
String description = path.evaluate("/inventory/products[" + i + "]/product/desc", doc);
int quantity = Integer.parseInt(path.evaluate("/inventory/products[" + i + "]/product/quantity", doc));
double price = Double.parseDouble(path.evaluate("/inventory/products[" + i + "]/product/price", doc));
Product pr = new Product(code, description, price, quantity);
addProduct(pr);
}
int transPurchased = Integer.parseInt(path.evaluate("count(inventory/transactions/purchased)", doc));
for (int i = 1; i <= transPurchased; i++) {
String code = path.evaluate("/inventory/transactions[" + i + "]/purchased/code", doc);
int count = Integer.parseInt(path.evaluate("/inventory/transactions[" + i + "]/purchased/count", doc));
find(code).purchased(count);
}
int transSold = Integer.parseInt(path.evaluate("count(inventory/transactions/sold)", doc));
for (int i = 1; i <= transSold; i++) {
String code = path.evaluate("/inventory/transactions[" + i + "]/sold/code", doc);
int count = Integer.parseInt(path.evaluate("/inventory/transactions[" + i + "]/sold/count", doc));
find(code).sold(count);
}
}
}
Product.java
public class Product {
private String code;
private String description;
private double price;
private int quantity;
/**
* Constructs a product with a specific code, description, price and
* quantity.
*
* @param code
* - product lookup code
* @param description
* - description of the product
* @param price
* - cost of one product
* @param quantity
* - number of products in inventory
*/
public Product(String newCode, String newDescription, double newPrice, int newQuantity) {
code = newCode;
description = newDescription;
price = newPrice;
quantity = newQuantity;
}
/**
* Increases the quantity of product when we've purchased products to
* replenish our supply.
*
* @param number
* the count of products purchased.
*/
public void purchased(int number) {
int newQuantity = quantity + number;
quantity = newQuantity;
}
/**
* Decrease the quantity of product when we've sold product to a customer.
*
* @param number
* the count of products sold.
*/
public void sold(int number) {
int newQuantity = quantity - number;
quantity = newQuantity;
}
/**
* Gets the quantity of this product.
*
* @return the current quantity
*/
public double getQuantity() {
return quantity;
}
/**
* Gets the code for this product.
*
* @return the product code
*/
public String getCode() {
return code;
}
/**
* Gets the code for this product.
*
* @return the product code
*/
public String getDescription() {
return description;
}
/**
* Gets the product's price.
*
* @return the product price
*/
public double getPrice() {
return price;
}
/**
* Get the total value in inventory of this product (quantity times price).
* return value
*/
public double getTotalValue() {
return quantity * price;
}
/**
* Change the product's price by a given percent.
*
* @param percent
* - percentage to change the product's price.
*/
public void adjustPrice(double percent) {
double change = price * (percent * 0.01);
// Round the change in price to two decimal points.
price = price + Math.round(change * 100.0) * 0.01;
}
/**
* Get a String that describes this Product.
*
* @return info about this product
*/
public String toString() {
return String.format("%s %s %d %.2f", code, description, quantity, price);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.