这更像是一个学习目的而不是真正需要的问题。 我使用下面的代码来检查xml文件是否有效。我不担心这里的模式验证。 我知道XMLStreamReader是一个接口,但我试图找到一些允许我做一些接近的实现:
Stream<String> s = reader.getText();
s.forEach(System.out::println);
//我没有lambda的完整代码
public interface CheckXml {
default boolean readFile(String f) throws IOException {
Boolean result = false;
FileInputStream inputStream = null;
try {
XMLInputFactory factory = XMLInputFactory.newInstance();
inputStream = new FileInputStream(f);
XMLStreamReader reader = factory.createXMLStreamReader(inputStream);
while (reader.hasNext()) {
reader.next();
}
} catch (IOException e) {
e.printStackTrace();
throw e;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return result;
}
//编辑
import com.iread.CheckXml;
public class CheckXmlFiles implements CheckXml {
}
//...
@Test
public void testXmlValidation() throws IOException {
CheckXml c = new CheckXmlFiles();
assertTrue("For simplicity it is expected 'true'", c.readFile("C:\\_pocs\\temp\\demo.xml"));
}
答案 0 :(得分:1)
您可以将XmlStreamReader
转换为流然后使用它。例如,它需要您创建一个调用hasNext
和next
方法的迭代器。
在实现的过程中有一些令人头疼的问题:XmlStreamReader会抛出已检查的异常,这会强制您创建一些额外的异常处理代码,这些代码会使代码膨胀。
另请注意,必须在迭代器内关闭XmlStreamReader
底层的流。如果您在外面关闭它,您将面临一些流关闭的异常。在这种情况下,您无法使用try with resources
。
我尝试创建一个简单的流和一个简单的测试,用于计算XML文件中可用元素的数量。
以下是一些玩具代码,用于演示您最终如何做到这一点:
public class XMLStreamReaderStream {
public static Stream<Integer> fromFile(File f) throws IOException, XMLStreamException {
XMLInputFactory factory = XMLInputFactory.newInstance();
Reader inputStream;
inputStream = new InputStreamReader(new FileInputStream(f), "UTF-8");
XMLStreamReader reader = factory.createXMLStreamReader(inputStream);
Iterator<Integer> iterator = new Iterator<>() {
public Integer next() {
try {
return reader.next();
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
public boolean hasNext() {
try {
boolean hasNext = reader.hasNext();
if (!hasNext) {
reader.close(); // close the stream here
}
return hasNext;
} catch (XMLStreamException e) {
return false;
}
}
public void forEachRemaining(Consumer<? super Integer> action) {
while (hasNext()) {
action.accept(next());
}
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
}
public static void main(String[] args) throws IOException, XMLStreamException {
File sampleXml = new File("stackoverflow1.xml");
LinkedHashMap<Integer, Long> xmlStats = fromFile(sampleXml).collect(Collectors.groupingBy(Function.identity(),
LinkedHashMap::new, Collectors.counting()));
Map<String, Long> readableMap = xmlStats.entrySet().stream().collect(Collectors.toMap(e -> {
Optional<Field> opt = Stream.of(XMLStreamConstants.class.getDeclaredFields()).filter(f -> {
try {
return e.getKey().equals(f.get(null));
} catch (IllegalAccessException e1) {
return false;
}
}).findFirst();
return opt.map(s -> s.toString().replaceAll(".+\\.", "")).orElseGet(() -> Integer.toString(e.getKey()));
}, Map.Entry::getValue));
System.out.println(readableMap);
}
}
此代码将计算XML文件中找到的标记类型,并将其打印到控制台:
{START_ELEMENT=22, END_DOCUMENT=1, END_ELEMENT=22, CHARACTERS=27}