如何使用Java中的SAXParser更新文件

时间:2017-09-28 05:13:06

标签: java xml saxparser

我正在使用SAX解析器从xml读取数据。现在我想使用SAX解析器修改数据。我怎么能这样做?

我的XML文件是,

<ProductCatalog>
    <item id="w1" type="SmartWatches">
        <name>Apple Watch</name>
        <price>400</price>
        <image>abc.jpg</image>
        <manufacturer>Apple</manufacturer>
        <condition>New</condition>
        <discount>10</discount>
        <accessories>
            <accessory>charger</accessory>
            <accessory>belt</accessory>
        </accessories>
    </item>

    <item id="w2" type="SmartWatches">
        <name>Apple Watch</name>
        <price>400</price>
        <image>abc.jpg</image>
        <manufacturer>Apple</manufacturer>
        <condition>New</condition>
        <discount>10</discount>
        <accessories>
            <accessory>charger</accessory>
            <accessory>belt</accessory>
        </accessories>
    </item>
</ProductCatalog>

这也是我在java中实现的SAX解析器。

public class UserHandler extends DefaultHandler {
    private Item item;
    private String value;
    private String filePath;
    private Map<String, Item> map = new HashMap<String, Item>();

    UserHandler(String filePath) {
        this.filePath = filePath;
        parseDocument();
        printValue();
    }

    private void printValue() {
        Set keys = map.keySet();
        for (Iterator i = keys.iterator(); i.hasNext();) {
            String key = (String) i.next();
            System.out.println("Key : " + key);

            Item itemDemo = map.get(key);
            System.out.println("Name : " + itemDemo.getName());
            System.out.println("Price : " + itemDemo.getPrice());
            System.out.println("Image : " + itemDemo.getImage());
            System.out.println("Manufacturer : " + itemDemo.getManufacturer());
            System.out.println("Condition : " + itemDemo.getCondition());
            System.out.println("Discount : " + itemDemo.getDiscount());
            System.out.println("Accessories : " + itemDemo.getAccessories().toString());
        }
    }

    private void parseDocument() {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            parser.parse(filePath, this);
        } catch (ParserConfigurationException e) {
            System.out.println("ParserConfig error");
        } catch (SAXException e) {
            System.out.println("SAXException : xml not well formed");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (qName.equalsIgnoreCase("item")) {
            item = new Item();
            item.setId(attributes.getValue("id"));
            item.setType(attributes.getValue("type"));
        }
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equals("item")) {
            map.put(item.getId(), item);
            return;
        }
        if (qName.equalsIgnoreCase("name")) {
            item.setName(value);
            return;
        }
        if (qName.equalsIgnoreCase("price")) {
            item.setPrice(value);
            return;
        }
        if (qName.equalsIgnoreCase("image")) {
            item.setImage(value);
            return;
        }
        if(qName.equalsIgnoreCase("manufacturer")){
            item.setManufacturer(value);
            return;
        }
        if(qName.equalsIgnoreCase("condition")){
            item.setCondition(value);
            return;
        }
        if(qName.equalsIgnoreCase("discount")){
            item.setDiscount(value);
            return;
        }
        if(qName.equalsIgnoreCase("accessory")){
            item.getAccessories().add(value);
            return;
        }
    }

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

如何修改XML文件中的特定属性?这些更改也应该在文件中复制。我不能使用DOM解析器。

1 个答案:

答案 0 :(得分:0)

首先,您似乎通过SAX解析器手动执行某些XML对象绑定。使用JAXB, which takes care of this for you会更有意义。由于您已经拥有了具有必要属性(getter / setter)的Item类,因此可能需要最少的JAXB注释和ProductCatalog类(带有项列表)才能使完全 unmarshal XML到对象,编组对象到XML。

根据您想要改变的方式,可能有几种方法。如果要更改XML的内容,而不是更改元素或属性的名称或更改名称空间,那么使用上面提到的JAXB将XML转换为Java对象,操作它们并将它们转换回XML就够了执行JAXB编组/解组的代码很少,其余的都是通过熟悉的Java代码处理POJO。

如果您想彻底改变XML的结构,或者重命名元素/属性,那么您可能希望查看XSLT, which is an XML-based transformation language。 Java中的XSLT处理快速而有效。需要一些时间来习惯,但是正确的思维方式XSLT成为一个非常强大的操作XML工具。

JAXB和XML转换API在很长一段时间内都是Java SE API的一部分,标准Java运行时包括JAXB 2和XSLT的默认实现1.实现是可插入的,以防您需要其他功能。例如Moxy,一种具有更高级绑定能力的JAXB实现,以及Saxon,一种XSLT 2的实现。

您甚至可以将这些技术结合起来。您可以在进行XSLT转换时从XML文件中使用JAXB解组Java对象,反之亦然:通过XSLT将Java对象发送到XML。