XML到JSON的动态转换

时间:2011-12-03 12:35:01

标签: java xml json

有没有办法(使用Java代码示例,如果可能的话)在运行时将XML输入转换为JSON,而不了解XML的实际内容和结构来源(文件,字符串等)?

例如,假设有一个非常大的XML数据集,其结构未知且具有多个嵌套级别,存储在一个大文本文件中。将所有内容读入内存是不可能的(因为空间不足),并且他们希望直接将其转换为JSON,即无需编写任何代码来检测和处理StAX标记(例如,START_ELEMENTCHARACTERSEND_ELEMENT)。

理想的解决方案是从转换器中获取ReaderInputStream,以便例如提供XML文件和ReaderInputStream生成JSON,将其提供给FileOutputStream,甚至直接提供给JSON解析器,如Jackson。如果这是不可能的,至少一种逐步读取XML文件的方法,转换为JSON并写入另一个文件将是一个可接受的妥协。

可以用于从/向XML / JSON转换的工具(例如,StaxONJSON-libJettisonXStream)似乎不会这样做但是只转换已知结构。

编辑:从OutputStream或Writer获取ReaderInputStream(也可以涵盖我上面谈到的“转换”),可以在虽然为了获得最佳结果和“无限”输入大小,但涉及多线程。解决方案在此article in Ostermiller.org中进行了描述,类似的实现可以在IO-Tools library中找到。

3 个答案:

答案 0 :(得分:5)

这是一个简单的例子,使用Java的内置StAX实现到parse XML和Jettison到produce JSONXMLEventWriter有一个方便的add(XMLEventWriter)方法,可以将读者与作家联系起来,这使得这非常简单:

import org.codehaus.jettison.mapped.MappedXMLOutputFactory;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import java.io.StringReader;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws Exception {
        String xml =
            "<root><foo>foo string</foo><bar><x>1</x><y>5</y></bar></root>";
        XMLEventReader reader = XMLInputFactory.newInstance()
            .createXMLEventReader(new StringReader(xml));
        XMLEventWriter writer = new MappedXMLOutputFactory(new HashMap())
            .createXMLEventWriter(System.out);
        writer.add(reader);
        writer.close();
        reader.close();
    }
}

我创建了一个自包含的Maven项目,展示了这个on Github

答案 1 :(得分:2)

您可以使用StAXON执行此操作,有关示例代码,请参阅https://github.com/beckchr/staxon/wiki/Converting-XML-to-JSON

答案 2 :(得分:1)

underscore-java库,其中包含来自XML和toJson的静态方法。我是该项目的维护者。

代码示例:

import com.github.underscore.lodash.U;
import java.util.Map;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class StringTest {

    @Test
    public void toJsonFromXml() {
        final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n"
            + "  <FirstItem>1</FirstItem>\n  <SecondItem>2</SecondItem>\n</root>";
        assertEquals("{\n"
            + "  \"root\": {\n"
            + "    \"FirstItem\": \"1\",\n"
            + "    \"SecondItem\": \"2\"\n"
            + "  }\n"
            + "}",
            U.toJson((Map<String, Object>) U.fromXml(xml)));
    }
}