繁体   English   中英

如何使用XMLStreamReader解析Java中的多个XML文件

[英]How to parse mulitple XML files in Java with XMLStreamReader

我们必须从生成器解析xml信息,该生成器为一堆气象站创建虚假的气象数据。 目前,我们只是在打印它,但稍后我们将对其进行处理。 但是,我们收到的数据包含多个XML“文件”。 有没有办法分离数据并在新的<?xml...?>处拆分数据? (数据是连续流,它会随机分割)我们的代码:

public class Main {

static private final int portNumber = Null;

public static void main(String[] args) {
    try {
        ServerSocket serverSocket = new ServerSocket(portNumber);
        Socket clientSocket = serverSocket.accept();

        BufferedReader clientReader = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));


        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = factory.createXMLStreamReader(clientReader);

        while (reader.hasNext()) {
            int event = reader.next();

            if (event == XMLStreamConstants.START_ELEMENT) {
                try {
                    String text = reader.getElementText();
                    System.out.println("Element Local Name:" + reader.getLocalName());
                    System.out.println("Text:" + text);

                } catch (XMLStreamException e) {
                    System.out.println(e);
                }
            }
            else if(event == XMLStreamConstants.END_ELEMENT){
                reader.close();
            }

        }
    } catch (IOException e) {
        System.out.println("Error: Unable to Start Server Socket\n\t" + e);
    } catch (XMLStreamException e){
        System.out.println(e);

    }
}
}

xml的示例(我们互相收到多个):

<?xml version="1.0"?>
<!-- The WEATHERDATA-element contains multiple MEASUREMENT-elements -->
<WEATHERDATA>
    <MEASUREMENT>
        <STN>123456</STN>

        <DATE>2009-09-13</DATE>

        <TIME>15:59:46</TIME>

        <TEMP>-60.1</TEMP>

        <DEWP>-58.1</DEWP>

        <STP>1034.5</STP>

        <SLP>1007.6</SLP>

        <VISIB>123.7</VISIB>

        <WDSP>10.8</WDSP>

        <PRCP>11.28</PRCP>

        <SNDP>11.1</SNDP>

        <FRSHTT>010101</FRSHTT>

        <CLDC>87.4</CLDC>

        <WNDDIR>342</WNDDIR>
    </MEASUREMENT>
</WEATHERDATA>

我们也有一个dtd文件,但不确定是否有帮助。

使用java.util.Scanner可以作为一种快速的解决方法。 disassemble()函数将跳过XML声明(如果存在),并将直到下一个结束</WEATHERDATA>标记(包括下一个标记)的所有字符组合到一个“字符串”中。 然后将结果传递到回调,在此示例中,该回调将XML转换为具有JAXB的POJO。

我不喜欢Scanner是它在内部缓冲输入流,因此关闭流时可能丢失最后一条消息。

public class DisassembleXml {
    private static final int port = 8888;
    private static final Pattern XML_DECL_PATTERN = Pattern.compile("<\\?xml.*?\\?>");
    private static final Pattern DATA_PATTERN = 
        Pattern.compile(".*?</WEATHERDATA>\\s+", Pattern.DOTALL);

    public static void main(String[] args) throws Exception {
        final ServerSocket serverSocket = new ServerSocket(port);
        System.out.printf("Listening on %d%n", serverSocket.getLocalPort());
        final Socket clientSocket = serverSocket.accept();
        System.out.printf("Processing from %s%n", clientSocket);

        try (Reader sr = new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.ISO_8859_1))
        {
            disassemble(sr, new ConvertToPojoAndPrint());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private static void disassemble(Reader reader, Consumer<String> xmlConsumer) {
        final Scanner sc = new Scanner(reader).useDelimiter("\\Z");
        try {
            while (true) {
                final String xml = sc
                    .skip(XML_DECL_PATTERN)
                    .findWithinHorizon(DATA_PATTERN, 0);
                if (xml == null || xml.isEmpty())
                    break;
                xmlConsumer.accept(xml);
            }
        }
        catch (Exception e) {
            throw new IllegalStateException("cannot interpret stream", e);
        }
    }

    private static class ConvertToPojoAndPrint implements Consumer<String>
    {
        final JAXBContext jaxbContext;
        final Unmarshaller unmarshaller;

        ConvertToPojoAndPrint() throws JAXBException {
            jaxbContext = JAXBContext.newInstance(WeatherData.class);
            unmarshaller = jaxbContext.createUnmarshaller();
        }

        @Override
        public void accept(String xml) {
            try {
                final WeatherData weatherData = (WeatherData) unmarshaller.unmarshal(new StringReader(xml));
                System.out.println("Another sample: " + weatherData);
            }
            catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }
    }

    @XmlRootElement(name = "WEATHERDATA")
    private static class WeatherData
    {
        @XmlElement(name = "MEASUREMENT")
        Measurement measurement;
        @Override
        public String toString() { return "WeatherData{" + "measurement=" + measurement + '}'; }
    }

    private static class Measurement
    {
        @XmlElement(name = "STN")
        String stn;
        // ... skipping the rest of elements for brevity
        @Override
        public String toString() { return "Measurement{" + "stn='" + stn + '\'' + '}'; }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM