2016-10-17 19 views
0

Hello guys我有以下與xml文件進行通信的代碼,找到給定用戶的名稱,然後更新其令牌值。藉助流和lambdas將迭代解決方案轉化爲功能

XML:

<app> 
    <user> 
     <name>Rick Alacidhbccgga Bushaksen</name> 
     <email>[email protected]</email> 
     <password>januszek</password> 
     <accessToken>666666666</accessToken> 
     <description>User has profile photo only</description> 
    </user> 
    <user> 
     <name>Rick Alacidhbccgga Bushaksen</name> 
     <email>[email protected]</email> 
     <password>brajan123</password> 
     <accessToken>bbb</accessToken> 
     <description>User doesn not have any photos</description> 
    </user> 
    <user> 
     <name>Rick Alacidhbccgga Bushaksen</name> 
     <email>[email protected]</email> 
     <password>ania123</password> 
     <accessToken>bbb</accessToken> 
     <description>User has profile and other photos</description> 
    </user> 
</app> 

這是我的方法,它可以完成上述:

public static void updateAccessTokenFunctional(FacebookTestUserAccount testUser) { 
     final String userName = getNameOfTestUser(testUser); 
     final String tokenValue = testUser.accessToken(); 
     try { 
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
      Document doc = docBuilder.parse(XML_FILE_NAME); 

      Node company = doc.getFirstChild(); 

      for (int j = 0; j < doc.getElementsByTagName("user").getLength(); j++) { 
       Node user = doc.getElementsByTagName("user").item(j); 

       NodeList listOfChildNodes = user.getChildNodes(); 
       String currentNameOfUser = ""; 
       for (int i = 0; i < listOfChildNodes.getLength(); i++) { 
        Node node = listOfChildNodes.item(i); 

        if ("name".equals(node.getNodeName())) 
         currentNameOfUser = node.getTextContent(); 

        if (currentNameOfUser.equals(userName) && "accessToken".equals(node.getNodeName())) { 
         node.setTextContent(tokenValue); 
        } 
       } 
      } 
      // saving content into xml file 
      TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
      Transformer transformer = transformerFactory.newTransformer(); 
      DOMSource source = new DOMSource(doc); 
      StreamResult result = new StreamResult(new File(XML_FILE_NAME)); 
      transformer.transform(source, result); 

     } catch (ParserConfigurationException pce) { 
      pce.printStackTrace(); 
     } catch (TransformerException tfe) { 
      tfe.printStackTrace(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } catch (SAXException sae) { 
      sae.printStackTrace(); 
     } 
    } 

    private static String getNameOfTestUser(FacebookTestUserAccount user) { 
     String[] arr = user.getUserDetails().split("\""); 
     return arr[3]; 
    } 

它工作正常,但我想將它重構爲實用的解決方案(如果可能的話),這是我要求幫助的部分。我曾嘗試類似

Stream.of(listOfChildNodes).///? 

,但我不能映射它得到單個節點...

回答

1

有是轉換NodeList或相似性的流沒有直接的方法。但你可以通過IntStream間接做到這一點。你可以寫一個助手到NodeList轉換成流是這樣的:

Stream<Node> toStream(NodeList nodeList) { 
    return IntStream 
      .range(0, nodeList.getLength()) 
      .mapToObj(nodeList::item); 
} 

然後獲得如在XML中的所有用戶名,你可以這樣做:

Stream<Node> userNodes = toStream(doc.getElementsByTagName("user")); 

List<String> userNames = userNodes 
     .flatMap(node -> toStream(node.getChildNodes()) 
       .filter(n -> n.getNodeName().equals("name"))) 
     .map(Node::getTextContent) 
     .collect(Collectors.toList()); 

只是要小心操作節點列表(刪除,添加節點),而它的工作,因爲這可能會導致意想不到的結果。