2016-03-21 139 views
-1

我有以下代碼以打破在Java循環不會使循環停止

File src = new File("C:\\Users\\Excel Files\\XLFile.xlsx"); 

    FileInputStream fis = new FileInputStream(src); 
    XSSFWorkbook wb = new XSSFWorkbook(fis); 
    XSSFSheet sh1 = wb.getSheetAt(0); 

    // Start 
    String chromePath = "C:\\Users\\chromedriver_win32\\chromedriver.exe"; 
    System.setProperty("webdriver.chrome.driver", chromePath); 

    WebDriver driver = new ChromeDriver(); 
    driver.manage().window().maximize(); 

    // UAT 
    driver.get("http://www.htmlcodetutorial.com/forms/_SELECT_MULTIPLE.html"); 
    //Building Action Interaction 
    Actions act = new Actions(driver); 

    if (sh1.getRow(0) !=null && sh1.getRow(0).getCell(1) !=null) { 
    List<WebElement> allopts = driver.findElements(By.xpath("//select[@name='toppings']//option")); 

    List<String> xlall= new ArrayList<String>(); 

    Iterator<Row> ixlrows = sh1.rowIterator(); 

    while (ixlrows.hasNext()) 
    { 
     Row row= ixlrows.next(); 

     if (row.getRowNum() > 0 && row.getCell(1) != null) 
     { 
      xlall.add(row.getCell(1).getStringCellValue()); 
     } 
    } 

    for (WebElement we : allopts) 
    { 
     if (xlall.contains(we.getText())) 
     { 
      act.keyDown(Keys.CONTROL) 
        .click(we) 
        .keyUp(Keys.CONTROL) 
        .build() 
        .perform(); 
     } 
    } 
} 
    wb.close(); 
    fis.close(); 

我做什麼是通過匹配從Excel裏的值,並將它們與應用程序選項將選擇匹配他們一個接一個。

這只是一個示例代碼,實際代碼有1003個選項,這個循環必須經過。只要找到excel中的值,我就想退出循環,並將它們與應用程序選項匹配並點擊它們。

正如你所看到的,我已經嘗試在if語句中放置break,並在if語句後嘗試。但沒有任何作品,它仍然在循環所有選項。

我在哪裏添加中斷來做到這一點?

P.S.除了循環在動作完成後被破壞以外,其他的都在工作。

P.S 2.這是使用Java的Selenium WebDriver代碼的一部分。

更新1:代碼更新

更新2:有沒有人覺得這個突破在此代碼無關與for循環本身,它存儲所有從數組列表中的應用程序選項allopts = ... 。?所以即使有休息,它也會繼續進行下去嗎?在那種情況下,我應該做些什麼來阻止陣列在看到選項並選擇它時立即捕獲所有選項?

UPDATE 3:還有另一條if語句。該代碼已更新與父母如果語句。

編輯:最後用@DonLeopardo的幫助下,像變魔術一樣,

這裏是工作代碼:

if (sh1.getRow(0) !=null && sh1.getRow(0).getCell(1) !=null) { 
    List<WebElement> allopts = driver.findElements(By.xpath("//select[@name='toppings']//option")); 

    List<String> xlall= new ArrayList<String>(); 

    Iterator<Row> ixlrows = sh1.rowIterator(); 

    while (ixlrows.hasNext()) 
    { 
     Row row= ixlrows.next(); 

     if (row.getRowNum() > 0 && row.getCell(1) != null) 
     { 
      xlall.add(row.getCell(1).getStringCellValue()); 
     } 
    } 

List<String> copy = new ArrayList<>(xlall) 

WebElement we; 
for(int i=0;i<allopts.size();i++) 
{ 
    we=(WebElement)allopts.get(i); 
    if (copy.contains(we.getText())) 
    { 
     act.keyDown(Keys.CONTROL) 
       .click(we) 
       .keyUp(Keys.CONTROL) 
       .build() 
       .perform(); 
     copy.remove(copy.indexOf(we.getText())); 
    } 
    if(copy.size()<1) 
    { 
     break; 
    } 
} 
+2

請編輯源代碼並對其進行格式化,以便我們可以得到您正在發佈的內容...... –

+0

您確定它實際上進入了if嗎? – DonLeopardo

+0

如果取消註釋第二個'break','for'循環只會處理'allopts'列表中的第一個元素,而不管if語句是否觸發,這使得下面的語句不可能:*「它仍然保留在循環所有選項「* – Andreas

回答

1

你可以嘗試這個選項,但我不知道他們是否會工作,因爲最初的代碼應該工作。 選項1:

boolean flag=true; 
int i=0; 
while(i<allopts && flag) 
{ 
if(conditons)//Put your conditions 
{ 
//code 
flag=false; 
} 
i++; 
} 

選項2:

boolean flag=false; 
for (WebElement we:allopts) 
{ 
if (condition)//Put your conditions 
{ 
//code 
flag=true; 
} 
if(flag) 
{ 
break; 
} 
} 

編輯: 方案3:(這個應該工作)

WebElement we; 
for(int i=0;i<allopts.size();i++) 
{ 
we=(WebElement)allopts.get(i); 
if (condition)//Put your conditions using we like always: xlall.contains(we.getText()) 
    { 
    //code 
    break; 
    } 
} 

我看,你不能停止foreach或類似的東西。

編輯2:我認爲我現在正確地理解了這個問題。 你應該這樣做:

List<String> allStrOpts=new ArrayList<String>(); 
for (WebElement we : allopts) 
{ 
    allStrOpts.add(we.getText()); 
} 
for(int i=0;i<xlall.size();i++) 
{ 
    if(allStrOpts.contains(xlall.get(i)) 
    { 
      act.keyDown(Keys.CONTROL) 
       .click(allopts.get(allStrOpts.indexOf(xlall.get(i)))) 
       .keyUp(Keys.CONTROL) 
       .build() 
       .perform(); 
    } 
} 

如果這需要大量的時間,你可以試試這個:

//List<String> copy=xlall.clone(); 

//or 

List<String> copy = new ArrayList<>(xlall) 

WebElement we; 
for(int i=0;i<allopts.size();i++) 
{ 
    we=(WebElement)allopts.get(i); 
    if (copy.contains(we.getText())) 
    { 
     act.keyDown(Keys.CONTROL) 
       .click(we) 
       .keyUp(Keys.CONTROL) 
       .build() 
       .perform(); 
     copy.remove(copy.indexOf(we.getText())); 
    } 
    if(copy.size()<1) 
    { 
     break; 
    } 
} 

我不知道哪一個具有更好的性能比較,我認爲第二個,但我不確定。我用來寫他們的順序是他們想到的順序。

+0

您認爲我添加的初始代碼中的這個中斷與for循環本身無關,它將應用程序中的所有選項存儲在數組列表中 allopts = ....?所以即使有休息,它也會繼續進行下去嗎? – Ami

+0

在那種情況下,我應該做些什麼來阻止陣列在它看到選項並選擇它時立即捕獲所有選項? – Ami

+0

在我的第二個選項中,如果替換flag = true;休息一下;應該可以工作,但是你說它沒有工作,我不知道爲什麼,但是我給你提供了其他應該工作的選項,我不知道他們是否會工作,也許問題是另一個。 – DonLeopardo

0

硒有Select類,你可以用它來選擇的選項

WebElement selectElement = driver.findElement(By.name("toppings")); // find the <select> tag 
Select select = new Select(selectElement); // initialize Select instance 

for (WebElement we : allopts) { 
    if (xlall.contains(we.getText())) { 
     select.selectByVisibleText(we.getText()); 
    } 
} 
+0

它不適用於我的實際應用程序,代碼編寫的方式工作得非常好,除非代碼在找到並選擇元素後不會中斷循環 – Ami

+0

請看看代碼現在有另一個父母如果聲明。對不起,感謝很多 – Ami

0

在您提供的代碼中,您應該在if聲明中放置break 。如果if的測試評估結果爲true,並且if塊中較早的方法都不引發異常,則break將跳出最近的封閉循環(或switch)。當然,一個異常也會導致執行離開你的示例代碼中的循環。

由於您似乎已經表明您已經嘗試過在其中放置break,所以我傾向於認爲您提供的代碼沒有充分地捕獲問題。這可能是因爲還有另一個循環級別沒有轉義,因爲您試圖插入的break位於switch語句內,或者因爲拋出稍後在循環中捕獲的異常而忽略了break

+0

代碼更新,非常感謝 – Ami

+0

@Ami,你的更新沒有任何改變改變了我的分析。如果你想在識別和處理一個選項後突破'for'循環,那麼你可以在處理完成後在'if'塊中加入一個'break'語句來實現。 –

+0

您認爲代碼中的這個中斷與for循環本身無關,它將數組中的所有選項都存儲在數組中list allopts = ....?所以即使有休息,它也會繼續進行下去嗎?在那種情況下,我應該做些什麼來阻止陣列在看到選項並選擇它時立即捕獲所有選項? – Ami