我们必须解析来自生成器的xml信息,该生成器为一堆天气预报器创建假天气数据。目前我们只是打印它,但我们以后必须用它来做。
但是,我们收到的数据包含多个XML&#34;文件&#34;。有没有办法分离数据并将其拆分为新的<?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文件,但我不确定这是否有用。
答案 0 :(得分:0)
使用java.util.Scanner
可以作为快速解决方法。 disassemble()
函数跳过XML声明(如果存在),并将所有字符组合到下一个结束</WEATHERDATA>
标记并包含在`String'中。然后将结果传递给回调,在此示例中,回调将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 + '\'' + '}'; }
}
}