从大型xml替换默认命名空间值

时间:2016-01-27 20:39:21

标签: java xml jaxb

我有一个大的xml文件,它有一个默认的命名空间值。如何在不使用java加载整个文件的情况下替换值?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer xmlns="http://www.example.org/package">
    <id>123</id>
</customer>

应该成为

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer xmlns="http://www.example.org/another">
    <id>123</id>
</customer>

2 个答案:

答案 0 :(得分:0)

&#34; hacky&#34;方式:流式传输文件(使用Reader和&#34; UTF-8&#34; charset)并进行字符串替换。

&#34;真实&#34;方法是使用SAX或最好使用StAX。您可以使用XMLEventReader和XMLEventWriter来流式传输xml并对其进行操作,而无需将整个内容加载到内存中。当您使用错误的命名空间获取元素事件时,使用正确的命名空间创建新的元素事件并将它们传递给编写器。

答案 1 :(得分:0)

如果您的新替换字符串与前一个字符串大小相同,有一种方法可以正常工作(或者如果替换字符串较小,则至少可以添加空格):

这是一个测试程序:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Test {

  public static void main( String[] args ) {
    try { 
      // NOTICE THE PACKAGE NAMES HAVE THE SAME SIZES
      String old_string = "xmlns=\"http://www.example.org/package\"";
      String new_string= "xmlns=\"http://www.example.org/another\"";

      RandomAccessFile raf = new RandomAccessFile( "test.xml", "rw" );
      String line;
      int byte_position = 0;
      while ( ( line = raf.readLine() ) != null ) {
        System.out.println( line );
        int index = line.indexOf( old_string );
        if( index !=-1 ) {
          raf.seek( byte_position + index );
          raf.writeBytes( new_string );
          raf.close();
          break;
        }
        // !!! +2 is for end line \n (use +4 if your end of lines is \n\r)
        byte_position += line.length() + 2; 
      }

    }
    catch ( Exception e ) {
      e.printStackTrace();
    }
  }
}

只是直接在右侧部分进行随机访问。 我从一行一行开始,但是当你在开始时寻找一些东西(第二行)时,它并不重要:之后有一段时间,所以你不读其他行...