0

我必须创建一个类来从我创建的名为 invoice.xml 的 xml 中提取数据。在 xml 中,客户可能会购买多个商品。打印提取的数据时的问题是,如果是这种情况,则只会打印客户购买的最后一个元素。有人可以提出解决方案吗?我还将附上我的 xml 文件,因为我很确定这就是问题所在。

SAXParserExample.java

package Attempt2;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParserExample extends DefaultHandler {

    List<Invoice> myInvoices;
    private String tempVal;
    private Invoice tempInv;

    public SAXParserExample() {
        myInvoices = new ArrayList<Invoice>();
    }

    public void runExample() {
        parseDocument();
        printData();
    }

    private void parseDocument() {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        try {
            SAXParser sp = spf.newSAXParser();
            sp.parse("invoice.xml", this);

        } catch (SAXException se) {
            se.printStackTrace();
        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (IOException ie) {
            ie.printStackTrace();
        }
    }

    private void printData() {
        System.out.println("\n\n\tNo of Invoices '" + myInvoices.size()
                + "'.\n");
        Iterator<Invoice> it = myInvoices.iterator();
        while (it.hasNext()) {
            System.out.println("\n\t" + it.next().toString());
        }
    }

    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        tempVal = "";
        if (qName.equalsIgnoreCase("Invoice")) {
            tempInv = new Invoice();
        }
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        tempVal = new String(ch, start, length);
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (qName.equalsIgnoreCase("invoice")) {
            myInvoices.add(tempInv);
        } else if (qName.equalsIgnoreCase("invoicenum")) {
            tempInv.setInvoiceNum(tempVal);
        } else if (qName.equalsIgnoreCase("title")) {
            tempInv.setTitle((tempVal));
        } else if (qName.equalsIgnoreCase("name")) {
            tempInv.setName((tempVal));
        } else if (qName.equalsIgnoreCase("street")) {
            tempInv.setStreet((tempVal));
        } else if (qName.equalsIgnoreCase("city")) {
            tempInv.setCity((tempVal));
        } else if (qName.equalsIgnoreCase("county")) {
            tempInv.setCounty((tempVal));
        } else if (qName.equalsIgnoreCase("postal")) {
            tempInv.setPostal((tempVal));
        } else if (qName.equalsIgnoreCase("description")) {
            tempInv.setDescription((tempVal));
        } else if (qName.equalsIgnoreCase("price")) {
            tempInv.setPrice((tempVal));
        } else if (qName.equalsIgnoreCase("quantity")) {
            tempInv.setQuantity((tempVal));
        }
    }

    public static void main(String[] args) {
        SAXParserExample spe = new SAXParserExample();
        spe.runExample();
    }

}

发票.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE people SYSTEM "invoice.dtd">
<invoices> 
    <invoice>
        <invoicenum>Invoice# 12345</invoicenum>
        <address>
            <title>Customer Address</title>
            <name>William Owen</name>
            <street>99 Anywhere Avenue</street>
            <city>Bangor</city>
            <county>Gwynedd</county>
            <postal>LL57 3JP</postal>
        </address>
        <items>
            <order>Items Ordered</order>
            <item>
                <description>Ink Jet Refill Kit</description>
                <price>29.50</price>
                <quantity>2</quantity>
            </item>
            <item>
                <description>4-Port Mini Hub</description>
                <price>19.95</price>
                <quantity>1</quantity>
            </item>
        </items>
    </invoice>
    <invoice>
        <invoicenum>Invoice# 12346</invoicenum>
        <address>
            <title>Customer Address</title>
            <name>Alex Gavra</name>
            <street>14 Menai View Terrace</street>
            <city>Bangor</city>
            <county>Gwynedd</county>
            <postal>LL57 2HF</postal>
        </address>
        <items>
            <order>Items Ordered</order>
            <item>
                <description>200GB External Disk Drive</description>
                <price>83.50</price>
                <quantity>1</quantity>
            </item>
        </items>
    </invoice>
    <invoice>
        <invoicenum>Invoice# 12347</invoicenum>
        <address>
            <title>Customer Address</title>
            <name>Mark Reeves</name>
            <street>Neuadd Llys Trifan</street>
            <city>Bangor</city>
            <county>Gwynedd</county>
            <postal>LL57 2JS</postal>
        </address>
        <items>
            <order>Items Ordered</order>
            <item>
                <description>19 Inch LCD Monitor LG</description>
                <price>120</price>
                <quantity>1</quantity>
            </item>
            <item>
                <description>Wireless mouse Laser Microsoft</description>
                <price>17.55</price>
                <quantity>1</quantity>
            </item>
        </items>
    </invoice>
    <invoice>
        <invoicenum>Invoice# 12348</invoicenum>
        <address>
            <title>Customer Address</title>
            <name>Nick Murray</name>
            <street>10 Some Street</street>
            <city>London</city>
            <county>London</county>
            <postal>WC1</postal>
        </address>
        <items>
            <order>Items Ordered</order>
            <item>
                <description>Microsoft keyboard SF200</description>
                <price>60.50</price>
                <quantity>1</quantity>
            </item>
            <item>
                <description>Screen cleaner spray</description>
                <price>4.59</price>
                <quantity>3</quantity>
            </item>
            <item>
                <description>Office chair</description>
                <price>149.99</price>
                <quantity>1</quantity>
            </item>
        </items>
    </invoice>
    <invoice>
        <invoicenum>Invoice# 12349</invoicenum>
        <address>
            <title>Customer Address</title>
            <name>Michael Jones</name>
            <street>Somewhere Street 18</street>
            <city>London</city>
            <county>London</county>
            <postal>E17</postal>
        </address>
        <items>
            <order>Items Ordered</order>
            <item>
                <description>PLX Elastic Bands</description>
                <price>15.73</price>
                <quantity>1</quantity>
            </item>
        </items>
    </invoice>
</invoices>

此外,在创建了我的 java 类之后,我在我的 xml 文档中收到以下消息,其中插入了多个项目:

在此处输入图像描述

我对 DTD 知之甚少,但这是我所写的:

发票.dtd

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT invoices (invoice*)>
<!ELEMENT invoice (invoicenum, address, items)>
<!ELEMENT address (title, name, street, city, county, postal)>
<!ELEMENT items (order, item)>
<!ELEMENT item (description, price, quantity)>

<!ELEMENT invoicenum (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT county (#PCDATA)>
<!ELEMENT postal (#PCDATA)>
<!ELEMENT order (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT quantity (#PCDATA)>

另外,我附上了 Invoice.java 类,以防有提示可以解决这个问题。

package Attempt2;

public class Invoice {

    private String invoicenum;
    private String title;
    private String name;
    private String street;
    private String city;
    private String county;
    private String postal;
    private String order;
    private String description;
    private String price;
    private String quantity;

    public Invoice() {
        System.out.println("\n\t No Arg Invoice Constructor Called…");
    }

    public Invoice(String invoicenum, String title, String name, String street,
            String city, String county, String postal, String order,
            String description, String price, String quantity) {
        System.out.println("\n\t 4-Argument Invoice Constructor Called…");
        this.invoicenum = invoicenum;
        this.title = title;
        this.name = name;
        this.street = street;
        this.city = city;
        this.county = county;
        this.postal = postal;
        this.order = order;
        this.description = description;
        this.price = price;
        this.quantity = quantity;

    }

    public String getInvoiceNum() {
        return invoicenum;
    }

    public void setInvoiceNum(String invoicenum) {
        this.invoicenum = invoicenum;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // street
    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    // city;
    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    // county
    public String getCounty() {
        return county;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    // postal
    public String getPostal() {
        return postal;
    }

    public void setPostal(String postal) {
        this.postal = postal;
    }

    // order
    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    // description
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    // price
    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    // quantity
    public String getQuantity() {
        return quantity;
    }

    public void setQuantity(String quantity) {
        this.quantity = quantity;
    }

    /**
    private String title;
    private String order;
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("Invoice Details \n---------------------------------\n");
        sb.append("Invoice Number:" + getInvoiceNum()+"\n");
        sb.append("Name:" + getName()+"\n");
        sb.append("Street:" + getStreet()+"\n");
        sb.append("City:" + getCity()+"\n");
        sb.append("County:" + getCounty()+"\n");
        sb.append("Postal Code:" + getPostal()+"\n");
        sb.append("Item Description:" + getDescription()+"\n");
        sb.append("Price:" + getPrice()+"\n");
        sb.append("Quantity:" + getQuantity()+"\n");
        return sb.toString();
    }
}
4

2 回答 2

0

由于我完全误解了您的问题并导致您整天误入歧途,因此我修复了您的解析器,因此它将项目作为单独的对象处理,现在您的发票包含项目列表。我道歉!

public class Item {
String description;
String price;
String quantity;

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getPrice() {
    return price;
}

public void setPrice(String price) {
    this.price = price;
}

public String getQuantity() {
    return quantity;
}

public void setQuantity(String quantity) {
    this.quantity = quantity;
}

@Override
public String toString() {
    final StringBuilder sb = new StringBuilder();
    sb.append("Item");
    sb.append("{description='").append(description).append('\'');
    sb.append(", price='").append(price).append('\'');
    sb.append(", quantity='").append(quantity).append('\'');
    sb.append('}');
    return sb.toString();
}

}

public class Invoice {
String invoiceNum;
String title;
String name;
String street;
String city;
String county;
String postal;
List<Item> items;

public Invoice() {
    this.items = new ArrayList<Item>();
}

public void addItem(Item item) {
    this.items.add(item);
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public String getCounty() {
    return county;
}

public void setCounty(String county) {
    this.county = county;
}

public String getInvoiceNum() {
    return invoiceNum;
}

public void setInvoiceNum(String invoiceNum) {
    this.invoiceNum = invoiceNum;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPostal() {
    return postal;
}

public void setPostal(String postal) {
    this.postal = postal;
}

public String getStreet() {
    return street;
}

public void setStreet(String street) {
    this.street = street;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}


@Override
public String toString() {
    final StringBuilder sb = new StringBuilder();
    sb.append("Invoice");
    sb.append("{city='").append(city).append('\'');
    sb.append(", invoiceNum='").append(invoiceNum).append('\'');
    sb.append(", title='").append(title).append('\'');
    sb.append(", name='").append(name).append('\'');
    sb.append(", street='").append(street).append('\'');
    sb.append(", county='").append(county).append('\'');
    sb.append(", postal='").append(postal).append('\'');
    sb.append(", items=").append(items);
    sb.append('}');
    return sb.toString();
}

}

public class SaxParserExample extends DefaultHandler {

List<Invoice> myInvoices;
private String tempVal;
private Invoice tempInv;
private Item tempItem;

public SaxParserExample() {
    myInvoices = new ArrayList<Invoice>();
}

public void runExample() {
    parseDocument();
    printData();
}

private void parseDocument() {
    SAXParserFactory spf = SAXParserFactory.newInstance();
    try {
        SAXParser sp = spf.newSAXParser();
        sp.parse("invoice.xml", this);

    } catch (SAXException se) {
        se.printStackTrace();
    } catch (ParserConfigurationException pce) {
        pce.printStackTrace();
    } catch (IOException ie) {
        ie.printStackTrace();
    }
}

private void printData() {
    System.out.println("No of Invoices '" + myInvoices.size());
    for (Invoice myInvoice : myInvoices) {
        System.out.println(myInvoice);
    }
}

public void startElement(String uri, String localName, String qName,
                         Attributes attributes) throws SAXException {
    tempVal = "";
    if ("Invoice".equalsIgnoreCase(qName)) {
        tempInv = new Invoice();
    } else if ("item".equalsIgnoreCase(qName)) {
        tempItem = new Item();
    }
}

public void characters(char[] ch, int start, int length)
        throws SAXException {
    tempVal = new String(ch, start, length);
}

public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if ("invoice".equalsIgnoreCase(qName)) {
        myInvoices.add(tempInv);
    } else if ("item".equalsIgnoreCase(qName)) {
        tempInv.addItem(tempItem);
    } else if ("invoicenum".equalsIgnoreCase(qName)) {
        tempInv.setInvoiceNum(tempVal);
    } else if ("title".equalsIgnoreCase(qName)) {
        tempInv.setTitle((tempVal));
    } else if ("name".equalsIgnoreCase(qName)) {
        tempInv.setName((tempVal));
    } else if ("street".equalsIgnoreCase(qName)) {
        tempInv.setStreet((tempVal));
    } else if ("city".equalsIgnoreCase(qName)) {
        tempInv.setCity((tempVal));
    } else if ("county".equalsIgnoreCase(qName)) {
        tempInv.setCounty((tempVal));
    } else if ("postal".equalsIgnoreCase(qName)) {
        tempInv.setPostal((tempVal));
    } else if ("description".equalsIgnoreCase(qName)) {
        tempItem.setDescription((tempVal));
    } else if ("price".equalsIgnoreCase(qName)) {
        tempItem.setPrice((tempVal));
    } else if ("quantity".equalsIgnoreCase(qName)) {
        tempItem.setQuantity((tempVal));
    }
}

public static void main(String[] args) {
    SaxParserExample spe = new SaxParserExample();
    spe.runExample();
}

}

于 2012-03-22T15:43:25.590 回答
0

DTD 说一个 <items> 元素只能有一个 <order> 元素和一个 <item> 元素。在 XML 文件中,您的 <items> 带有两个<item> 元素,这对于 DTD 来说是错误的。

如果 <tems> 可能有多个 <item> 元素,一种解决方案是更改 DTD 的以下行

<!ELEMENT 项目(订单、项目)>

<!ELEMENT 项目(订单,项目+)>

XML文件中的以下行也是错误的:

<!DOCTYPE people SYSTEM "invoice.dtd">

它应该是

<!DOCTYPE发票系统“invoice.dtd”>

DTD中没有人员元素定义

于 2012-03-22T16:23:40.610 回答