在Java中复制XML文件以写入新的XML文件

在Java中复制XML文件以写入新的XML文件,java,xml,file-io,xml-parsing,bufferedreader,Java,Xml,File Io,Xml Parsing,Bufferedreader,我想知道是否有人知道是否可以使用Java中的一个XML解析器逐行读取XML文档中的每一行,并基本上在另一个XML文件中复制相同的文档?(在我的例子中,只取文档中从X点到Y点的行并复制它们)。我曾考虑在一个小的试运行中使用bufferedreader和bufferedwriter,但它并没有正确地输出文件。下面是我在试运行中所做的,但这不是我想要的。那么,有没有人对此有任何经验,或者有什么想法或建议可以提供?先谢谢你 JAVA代码 public class IPDriver { publ

我想知道是否有人知道是否可以使用Java中的一个XML解析器逐行读取XML文档中的每一行,并基本上在另一个XML文件中复制相同的文档?(在我的例子中,只取文档中从X点到Y点的行并复制它们)。我曾考虑在一个小的试运行中使用bufferedreader和bufferedwriter,但它并没有正确地输出文件。下面是我在试运行中所做的,但这不是我想要的。那么,有没有人对此有任何经验,或者有什么想法或建议可以提供?先谢谢你

JAVA代码

public class IPDriver 
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new FileReader("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne/word/document.xml"));
        BufferedWriter writer = new BufferedWriter(new FileWriter("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne/word/tempdocument.xml"));

        String line = null;

        while ((line = reader.readLine()) != null)
        {
            writer.write(line);
        }

        // Close to unlock.
        reader.close();
        // Close to unlock and flush to disk.
        writer.close();
    }
}
由于Ted Hopp,JAVA代码可以正常工作

public class IPDriver 
    {
        public static void main(String[] args) throws IOException
        {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne/word/document.xml"), "UTF-8"));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne/word/tempdocument.xml"), "UTF-8"));

            String line = null;

            while ((line = reader.readLine()) != null)
            {
                writer.write(line);
            }

            // Close to unlock.
            reader.close();
            // Close to unlock and flush to disk.
            writer.close();
        }
    }

您可以轻松地将读者和作者与StAX链接。使用该API,您还可以轻松创建一个过滤器,以仅提取所需文档的部分。以下是一些可能有帮助的链接:


如果您的代码没有正确复制文件,我猜您有字符编码问题。由于XML的默认编码是UTF-8,而FileReader的默认编码是平台的默认编码,因此我建议改为:

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
        new FileInputStream("...input file path..."),
        "UTF-8"
    )
);
BufferedWriter writer = new BufferedWriter(
    new OutputStreamWriter(
        new FileOutputStream("...output file path..."),
        "UTF-8"
    )
);
XML解析器将为您提供元素(或元素事件),而不是行。例如,他们无法区分空白区域的变化:

<tag attr1="val1" attr2="val2" />

与:

<tag attr1="val1"
     attr2="val2"
     />


如果您的需求包括区分这两种情况,那么XML解析器方法将不起作用。

如果您只是想要一个副本,请不要犯使用读取器的新手错误,而是使用InputStream/OutputStream进行复制。即使有读者,你为什么要逐行阅读呢?只需读取缓冲区中的全部字符


那么为什么要避开读者呢?因为它增加了将字节解码为字符的开销(并且需要编写器将字符编码为字节),这对您没有任何价值。如果您犯了另一个常见错误,没有为读写器指定要使用的编码,那么将使用任何平台默认编码,该编码可能是,也可能不是您正在读取的文件正在使用的编码。

为什么不起作用?它是否给出了一个错误或什么?输出出了什么问题?我猜您想使用XML解析器来获得更好的控制/输出?我这样评论是因为上面的示例代码根本不使用解析器。基本上,在Ted的解决方案之前,我得到了原始XML文档的1/20,然后在新文档中报告了一个涉及某个样式表错误的错误。@Ted Hopp,这行得通!非常感谢你。然而,对于我正在努力做的事情。我不确定到底要添加什么到我的代码中,以便只废弃我想要的部分。例如,我希望能够识别存储在上述示例中的“val”实例……刮除该“行”下的所有内容,直到找到另一个“val”实例。这可能吗?我认为,这取决于您对文件内容的控制程度、XML结构的复杂程度以及您在寻找什么。我倾向于使用DOM解析器,做一些小手术来消除我不想要的东西,从修改后的DOM生成XML,并忍受格式的丢失。然而,如果您有一个足够简单的文档结构,您也许可以使用正则表达式搜索实现自己的粗略解析。诀窍是仔细考虑文档中可能会弄乱代码的所有内容,然后进行防御。这不是一项容易的任务。如果您需要来自XML的数据,您应该使用XML解析器——这是XML的一条基本规则。您不需要解析的唯一情况是,您正在进行盲拷贝。@Ted Hopp,@StaxMan我的经验(到目前为止)是使用SAX解析器来提取我在给定xml文档中寻找的必要属性。在本例中,我之所以不愿意使用解析器,是因为(加上我之前所说的)除了在heading1和heading2之间进行抓取之外,我还想确定两个标题之间是否存在“image”的实例。如果是这样的话,那么我希望将该部分保存在一个单独的文档中,并通过该文档进行解析,以查找目标属性(很可能是SAX)。@Ted Hopp,@StaxMan然而,我相信解析器只能向下读取,而不能向上读取。因此,如果我要使用解析器识别一个image实例,我将无法删除它上面的部分。因此,我不确定现在该怎么做/我将与StAX合作,但我刚刚开始熟悉SAX,并将其纳入了我项目的一个阶段。你认为StAX和SAX有多大不同?使用SAX通常就像试图爬上树,屁股先爬。或者用反波兰符号书写表达式。或者,在CS语言中:它是基于事件循环(侦听器)的,因此您最终会编写处理程序,跟踪状态,以及所有的复杂性。斯塔克斯更直截了当;使用游标(XMLStreamReader)按照XML文档中的顺序读取内容;就像他说的,StAX是基于pull-cursor的,而不是SAX的push模型。这使它非常适合我认为你要做的事情。您将使用更少的代码和更直观的代码来完成这项工作。也就是说,您当然可以使用SAX来完成这项工作。你可以利用这个机会为你的实习项目学习这两个方面。这将是值得花费的时间。