如何循环使用lambda的XMLStreamReader

问题描述:

这对于学习的目的而言,是一个比真正需要更多的问题。 我正在使用下面的代码来检查一个xml文件是否有效。我不担心这里的模式验证。 我知道的XMLStreamReader是一个接口,但我试图找到一些FPGA实现,让我做一些接近:如何循环使用lambda的XMLStreamReader

 Stream<String> s = reader.getText(); 
     s.forEach(System.out::println); 

//我的完整代码,而无需拉姆达

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

您的“没有lambda的完整代码”对我来说看起来并不完整。它应该至少包含获得你想要在'Stream '中输入的字符串的代码。 – Eran

+0

创建一个'Iterator ',其中'Something'是''while'期间想要出的东西 - 例如'XMLElement'或'Person'。将'Iterator'包裹在'Spliterator'中。从Spliterator创建一个Stream。 –

+0

@坦率地说,我不知道这个问题有什么关系,但是在这里;我加入了我的问题 – DemeCarv

您可以将XmlStreamReader转换为流,然后使用它。它需要您创建一个迭代器,例如调用hasNextnext方法。

执行过程中有一些令人头痛的事情: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}