我正在使用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解析器。
答案 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。