如何使用Java高效地修改庞大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

我需要读取一个大约1MB的巨大XML文件,只修改其中的一小部分,而不需要封送完整的XML文件。 例如:


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>