如何使用Java高效地修改庞大XML的一小部分
我需要读取一个大约1MB的巨大XML文件,只修改其中的一小部分,而不需要封送完整的XML文件。 例如:如何使用Java高效地修改庞大XML的一小部分,java,xml,dom,jaxb,sax,Java,Xml,Dom,Jaxb,Sax,我需要读取一个大约1MB的巨大XML文件,只修改其中的一小部分,而不需要封送完整的XML文件。 例如: 11 汤姆 地址行1 1234567890 纽约 567890 12345 从上面的XML中,我只想读取address元素并进行更新,保持其他元素不变。 因此,上面的XML应该是: <student id = "10"> <age>11</age> <name>Tom</name> &l
11
汤姆
地址行1
1234567890
纽约
567890
12345
从上面的XML中,我只想读取address元素并进行更新,保持其他元素不变。
因此,上面的XML应该是:
<student id = "10">
<age>11</age>
<name>Tom</name>
<address>Updated Address</address>
<phone>1234567890</phone>
<city>NY</city>
<zip>567890</zip>
<postal>12345</postal>
</student>
11
汤姆
更新地址
1234567890
纽约
567890
12345
然而,在XML的下面,我失去了其他元素:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<student>
<address>Updated Address</address>
</student>
更新地址
我正在尝试使用JAXB和以下代码:
// we need a blank document to store final xml output
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
Document document = docBuilder.parse("student.xml");
// create JAXBContext which will be used to create a Binder
JAXBContext jc = JAXBContext.newInstance(Student.class);
Binder<Node> binder = jc.createBinder();
// set output as formatted one
binder.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// get xml node from the document
Node xmlNode = document.getDocumentElement();
// Returns the updated JAXB object
Student st = (Student) binder.updateJAXB(xmlNode);
//Update Address
st.setAddress("Updated Address");
// update xml node with new data
xmlNode = binder.updateXML(st);
// set node value to the document
document.setNodeValue(xmlNode.getNodeValue());
// finally print the edited object on stdout
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(System.out));
@XmlRootElement
public class Student{
public String getAddress() {
return address;
}
@XmlElement
public void setAddress(String address) {
this.address = address;
}
String address;
}
//我们需要一个空白文档来存储最终的xml输出
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder=dbf.newDocumentBuilder();
Document=docBuilder.parse(“student.xml”);
//创建用于创建活页夹的JAXBContext
JAXBContext jc=JAXBContext.newInstance(Student.class);
Binder Binder=jc.createBinder();
//将输出设置为格式化输出
setProperty(Marshaller.JAXB_格式化的_输出,true);
//从文档中获取xml节点
节点xmlNode=document.getDocumentElement();
//返回更新的JAXB对象
Student st=(Student)binder.updateJAXB(xmlNode);
//更新地址
st.setAddress(“更新地址”);
//使用新数据更新xml节点
xmlNode=binder.updateXML(st);
//将节点值设置为文档
setNodeValue(xmlNode.getNodeValue());
//最后在标准输出上打印编辑的对象
TransformerFactory tf=TransformerFactory.newInstance();
变压器t=tf.新变压器();
t、 转换(新的DOMSource(文档)、新的StreamResult(System.out));
@XmlRootElement
公立班学生{
公共字符串getAddress(){
回信地址;
}
@XmlElement
公共无效设置地址(字符串地址){
this.address=地址;
}
字符串地址;
}
哪种Java解析机制可以用来实现这一点?另外,哪一个在内存和时间方面更有效?现在一兆字节不是很大。实际上,完成这项工作最简单、最有效的工具是XSLT。使用XSLT 3.0,它非常接近于一行程序(加上一些样板文件):
更高效、更快:基于SAX的解析。无论如何,1MB的XML不是一个巨大的XML。您甚至可以使用XQuery来实现这一点,这是一个较慢的选择。
// we need a blank document to store final xml output
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
Document document = docBuilder.parse("student.xml");
// create JAXBContext which will be used to create a Binder
JAXBContext jc = JAXBContext.newInstance(Student.class);
Binder<Node> binder = jc.createBinder();
// set output as formatted one
binder.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// get xml node from the document
Node xmlNode = document.getDocumentElement();
// Returns the updated JAXB object
Student st = (Student) binder.updateJAXB(xmlNode);
//Update Address
st.setAddress("Updated Address");
// update xml node with new data
xmlNode = binder.updateXML(st);
// set node value to the document
document.setNodeValue(xmlNode.getNodeValue());
// finally print the edited object on stdout
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(System.out));
@XmlRootElement
public class Student{
public String getAddress() {
return address;
}
@XmlElement
public void setAddress(String address) {
this.address = address;
}
String address;
}
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="student[@id='10']/address/text()">Updated address</xsl:template>
</xsl:transform>