【问题标题】:Replace default namespace value from large xml从大型 xml 替换默认命名空间值
【发布时间】:2016-05-05 00:08:43
【问题描述】:

我有一个具有默认命名空间值的大型 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>

【问题讨论】:

  • 你已经尝试了什么?
  • 从 stackoverflow 获得答案
  • 使用文本编辑器?还是 sed 进行流编辑?
  • 对不起,如果我不清楚。我需要用 java 来做这个。
  • 您需要替换磁盘上文件中的值吗?还是需要在内存中修改以供以后处理?

标签: java xml jaxb


【解决方案1】:

有一种“hacky”方式:流式传输文件(使用 Reader 和“UTF-8”字符集)并进行字符串替换。

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

【讨论】:

    【解决方案2】:

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

    这是一个测试程序:

    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();
        }
      }
    }
    

    所做的只是直接在右侧部分进行随机访问。 我从逐行阅读开始,但是当您在开始时(第二行)寻找一些东西时,这并不重要:之后有一个休息,所以您不会阅读其他行...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多