使用SAX解析器合并XML

时间:2015-02-05 20:43:41

标签: java xml

我查看了以下链接中的讨论 - Merging xml file using java NodeList

我只需要使用相同的功能使用SAX解析器,因为我只需要合并两个文件,但它们的大小非常大。

请帮忙。

档案1

<root>
    <Item>
        <a>jhiuo55jhj</a>
        <b>jhjoiohj</b>
        <c>jhjh334j</c>
    </Item>
</root>

文件2

<root>
    <Item>
        <x>jhi99jhj</x>
        <y>jhyty66jhj</y>
        <z>jhxdx3jhj</z>
    </Item>
</root>

预期输出

<root>
    <Item>
        <a>jhiuo55jhj</a>
        <b>jhjoiohj</b>
        <c>jhjh334j</c>
        <x>jhi99jhj</x>
        <y>jhyty66jhj</y>
        <z>jhxdx3jhj</z>
    </Item>
</root> 

2 个答案:

答案 0 :(得分:0)

基本解决方案,不包括命名空间或属性

  • 使用XMLStreamWriter将处理程序中的内容接收到一个输出
  • 跳过根元素,因此我们不会将它们放在输出中两次

代码

public class XmlMerger {

    public static void main(String[] args) throws Exception {
        FileOutputStream outputStream = new FileOutputStream("output.xml");
        XMLStreamWriter out = XMLOutputFactory.newInstance().createXMLStreamWriter(new OutputStreamWriter(outputStream));

        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();

        Handler handler = new Handler(out);
        out.writeStartDocument();
        out.writeStartElement("root");
        saxParser.parse(new File("input1.xml"), handler);
        saxParser.parse(new File("input2.xml"), handler);
        out.writeEndElement();
        out.close();
    }

    private static class Handler extends DefaultHandler {

        private XMLStreamWriter out;
        private boolean dumping;

        public Handler(XMLStreamWriter out) {
            this.out = out;
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

            if ("root".equals(qName)) {
                dumping = true;
            } else {
                try {
                    out.writeStartElement(qName);
                    // TODO attributes if you need them...
                } catch (XMLStreamException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("root".equals(qName)) {
                dumping = false;
            } else {
                try {
                    out.writeEndElement();
                } catch (XMLStreamException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void characters(char ch[], int start, int length) throws SAXException {
            if (!dumping) {
                return;
            }
            try {
                out.writeCharacters(ch, start, length);
            } catch (XMLStreamException e) {
                e.printStackTrace();
            }
        }

    }
}

答案 1 :(得分:0)

我会说你在这里采用SAX-DOM方法来获得更好的性能。

让我们说下面是输入的xml文件

1) First.xml
<root>
    <Item>
        <a>1</a>
        <b>2</b>
        <c>3</c>
    </Item>
    <Item>
        <a>1</a>
        <b>2</b>
        <c>3</c>
    </Item>
</root>
2) Second.xml
<root>
    <Item>
        <x>11</x>
        <y>22</y>
        <z>33</z>
    </Item>
    <Item>
        <x>44</x>
        <y>55</y>
        <z>66</z>
    </Item>
</root>

合并这些xmls的步骤:

  1. 使用DOM
  2. 读取First.xml
  3. 现在开始使用SAX
  4. 阅读Second.xml
  5. 保持计数器变量 i
  6. 每当SAX解析器为 Item 节点找到 startElement 时,从第i个Item节点的First.xml中获取其他字段,该节点存储在DOM中。
  7. 我+ +
  8. 将内容写入OutputStream
  9. 解析完毕,关闭Outputstream