0

我正在使用 jsoup 进行 HTML 表格解析。下面是我必须识别正确段的场景。识别正确段的过程是:
无论我在哪里找到关键字-> ABC,我都必须迭代直到获得<tr>HTML 标记(用于表识别),然后检查它是否包含所有 4 个关键字ForVoteAgainstVoteAbsentNoVotes第一行(如果没有,则转到下一次出现的关键字-> ABC)并遵循相同的过程。一旦我得到匹配表内的 4 个投票关键字,我就可以提取表中的数字。

我遇到的问题是:如果关键字ABC只出现一次,我可以解析。但是当ABC 不止一次出现导致解析错误的段时,就无法做到这一点
我要解析的示例 HTML 代码是:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="ISO-8859-1">
			<title>Correct segment to be identified for parsing table </title>
		</head>
		<body>
			<div>ABC Keyword</div>
			<!--First Occurrence of Keyword(Not a correct segment as the table below doesn't have the correct headers)-->
			<div> asd xyz asdf</div>
		</br>
		<table border="1px">
			<tbody>
				<tr>
					<td>For Vote</td>
					<td>Against Vote</td>
					<td>Some Header1</td>
					<td>Some Header2</td>
				</tr>
				<tr>
					<td>1</td>
					<td>1</td>
					<td>2</td>
					<td>3</td>
				</tr>
			</tbody>
		</table>
		<div>
			<p>Another 'ABC' is the keyword in the document</p>
			<!--2nd Occurence, but not correct segment-->
		</div>
		<div> asd xyz jskadl</div>
	</br>
	<div> ABC is keyword  </div>
	<!-- 3rd Occurrence, this is the correct segment below which the required table with keywords ForVote, AgainstVote, Absent, NoVotes are found whose values are to be parsed-->
</br>undefined</br>undefined<div>
<table border="1px">
	<tbody>
		<tr>
			<td>ForVote</td>
			<td>AgainstVote</td>
			<td>Absent</td>
			<td>NoVotes</td>
		</tr>
		<tr>
			<td>10</td>
			<td>5</td>
			<td>1</td>
			<td>0</td>
		</tr>
	</tbody>
</table>
</div>
<p>Doc ends</p>
</body>
</html>

Java 代码

我的逻辑是迭代直到找到 ABC。找到包含 ABC 的元素,为其添加一个 class=tagid。选择(div.tagid)。然后找到<tr>标签。查找表格是否为预期格式,即代码中的 isVertical=0。然后检查第一行中是否存在所有四个关键字。如果是,则解析数值。在多次出现“ABC”的情况下不起作用:-(

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final static String regexPattern1 = "ABC";
final static String tableregexPattern1 = "ForVotes";
final static Pattern tPat1 = Pattern.compile(tableregexPattern1);

//a function for finding occurrence of ABC  
public static Element htmlIterator(String HTMLTags, String regexPattern) throws IOException {       
pattern = Pattern.compile(regexPattern1, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);// compiles the matching regex
    for (String tag : HTMLTags) {
        Elements tagData = doc.select("div");
        for (Element element1 : tagData) {
            if (element1.select("div").text().trim().equals("")) {
                continue;
            } else {

                final String dataParsedInTag = element1.select("div").text().trim();
                final String dataParsedInTagClean = dataParsedInTag.replace(",", "");
                final Matcher matcher = pattern.matcher(dataParsedInTagClean);
                b1 = matcher.find();
                if (b1) {
                    System.out.println(b1 + " matched");
                    return element1;
                        }
                   }
            }
    }
    public static void main{  

doc=Jsoup.parseHTML(input);     //input is above given HTML snippet
element1 = htmlIterator(div, regexPattern1);// returns the element which has "ABC"
    Elements ele = element1.getElementsMatchingText(pattern);
    if(ele != null) {
        Elements manipulatedElement = ele.addClass(tagid);//attach class= tagid to the identified div
        //iterate till I get <tr>
        while (true) {
                resultTableHTML = doc.selectFirst(div+"."+tagid).nextElementSibling();
                resultTableInChar = doc.selectFirst(div+"."+tagid).nextElementSibling().toString();
                nextResultTable = doc.selectFirst(div+"."+tagid).nextElementSibling();
                // System.out.println(resultTableInChar);
                while (!resultTableInChar.contains("tr")) {
                    resultTableInChar = nextResultTable.nextElementSibling().toString();
                    nextResultTable = nextResultTable.nextElementSibling();// for continuous iteration
                    System.out.println("-->Iterating" + nextResultTable);
                }
                break;

    }
    //check if the table is having the keyword ForVotes and is int the expected tabular format that is an isVertical=0
    Elements rows = nextResultTable.select("tr");// just select the rows and check if its empty or not
            for (Element rowElement : rows) {
                Matcher mat1 = tPat1.matcher(rowElement.text());
                boolean isTablewithFirstHeaderKeyword =  mat1.find();
                if (!(rowElement.text().isEmpty()) && (isTablewithFirstHeaderKeyword)  ) {
                    String tmpLines[] = rowElement.text().trim().replaceAll(",", "").split(" ");
                    String tmpRowElement = rowElement.text().trim().replaceAll(",", "");
                    Matcher mat5 = tPat5.matcher(tmpRowElement);
                    boolean typeVerticaldetected = mat5.find();//for detecting the numerical values
                    if (typeVerticaldetected) {
                        isVertical = 1;
                        break;
                    } else {
                        isVertical = 0;
                        break;
                    }

                }

            }
            if (isVertical == 0) {
                System.out.println("Horizontal Table Identified. Start Parsing.....");
                rows = nextResultTable.select("tr");
                for (Element rowElement : rows) {  

//if row isn't empty then find all 4 keywords
                    if (!rowElement.text().isEmpty()) {
                        Matcher mat1 = tPat1.matcher( rowElement.toString());//tpat1 is regex for ForVotes inside table row, CAN use contains for now
                        Matcher mat2 = tPat2.matcher( rowElement.toString());//tpat2 is regex for AgainstVotes inside table row
                        Matcher mat3 = tPat3.matcher( rowElement.toString());//tpat3 is regex for Absent inside table row
                        Matcher mat4 = tPat4.matcher( rowElement.toString());//tpat4 is regex for NoVotes inside table row
                        boolean hasTableHeaderKeywords = mat1.find() && mat2.find() && mat3.find() && mat4.find();
                        System.out.println(mat1.find()+";"+mat2.find()+";"+mat3.find()+";"+mat4.find()+";");

                        if(hasTableHeaderKeywords) {
                            rowElement = rowElement.nextElementSibling();



                            String tmpLines[] = rowElement.text().trim().replaceAll(",", "").split(" ");

                            Matcher mat5 = tPat5.matcher(tmpLines[0]);//tpat5 is regex for numerical digits inside table 2nd row
                            Matcher mat6 = tPat5.matcher(tmpLines[1]);
                            Matcher mat7 = tPat5.matcher(tmpLines[2]);
                            Matcher mat8 = tPat5.matcher(tmpLines[3]);

                            System.out.println(mat5.matches());
                            System.out.println(mat6.matches());
                            System.out.println(mat7.matches());
                            System.out.println(mat8.matches());


                            if (mat5.matches())
                            {
                            for(int index=0 ; index < tmpLines.length ; index++) {
                                System.out.println("Value at index-> "+index+" is : "+tmpLines[index]);
                            }

                            System.out.println("For : "+ tmpLines[0] + "|" +"Against : "+ tmpLines[1] + "|" + "Abstain : "+tmpLines[2] + "|" +"Broker Non-Votes : "+ tmpLines[3]);
                            break;
                            }
                            else {

                                System.out.println("Numerical Values werent found in expected range for"+tmpLines);
                            }
                        }
4

0 回答 0