is there anyway nth previous or next specific html element possibly on different nesting level using jsoup?
html example:
<div style="position: relative;"> <div class="wmd-container"> <div id="wmd-button-bar-42" class="wmd-button-bar"></div> <input id="previousinput" name="communitymode" type="checkbox"> </div> </div> <div class="fl" style="margin-top: 8px; height: 24px;"> </div> <div id="draft-saved-42" class="draft-saved community-option fl" style="margin-top: 8px; height: 24px; display: none;">draft saved </div> <div id="draft-discarded-42">draft discarded</div> <div class="community-option g-row ai-center f-checkbox"> <div class="g-col -input"> <input id="nextinput" name="communitymode"> </div> <div class="g-col"> <label for="communitymode-42">community wiki</label> </div> </div>
for example in below html pointing element:
<div id="draft-discarded-42">draft discarded</div>
by using below code.
element elem = doc.select("div[id=draft-discarded-42]").first();
i want first previous input
element:
<input id="previousinput" name="communitymode" type="checkbox">
and second previous div
:
<div class="fl" style="margin-top: 8px; height: 24px;"> </div>
and second next div
:
<div class="g-col -input"> <input id="nextinput" name="communitymode"> </div>
unless don't know id
attribute's value or attribute can use identify element , should use selector syntax element want.
however, if have vague idea/don't know element's attributes, know occurrence relating pointed element, can use these functions:
nth previous occurrence of element matching query:
public static element selectnthelementbefore(element origin, string query, int count) { element currentelement = origin; evaluator evaluator = queryparser.parse(query); while ((currentelement = currentelement.previouselementsibling()) != null) { int val = 0; if (currentelement.is(evaluator)) { if (--count == 0) { return currentelement; } val++; } elements elems = currentelement.select(query); if (elems.size() > val) { int childcount = elems.size() - val; int diff = count - childcount; if (diff == 0) { element prevelement = elems.first(); currentelement = prevelement.children().select(query).first(); while (currentelement != prevelement) { if (currentelement == null) { return prevelement; } prevelement = currentelement; currentelement = currentelement.children().select(query).first(); } } if (diff > 0) { count -= childcount; } if (diff < 0) { return elems.get(childcount - count); } } } if (origin.parent() != null && currentelement == null) { if (origin.parent().is(evaluator)) { if (--count == 0) { return origin.parent(); } } return selectnthelementbefore(origin.parent(), query, count); } return currentelement; }
nth next occurrence of element matching query:
public static element selectnthelementafter(element origin, string query, int count) { element currentelement = origin; evaluator evaluator = queryparser.parse(query); while ((currentelement = currentelement.nextelementsibling()) != null) { int val = 0; if (currentelement.is(evaluator)) { if (--count == 0) return currentelement; val++; } elements elems = currentelement.select(query); if (elems.size() > val) { int childcount = elems.size() - val; int diff = count - childcount; if (diff == 0) { return elems.last(); } if (diff > 0) { count -= childcount; } if (diff < 0) { return elems.get(childcount + diff); } } } if (origin.parent() != null && currentelement == null) { return selectnthelementafter(origin.parent(), query, count); } return currentelement; }
usage:
element elem = doc.getelementbyid("draft-discarded-42"); element firstprevinput = selectnthelementbefore(elem, "input", 1); element secprevdiv = selectnthelementbefore(elem, "div", 2); element secnextdiv = selectnthelementafter(elem, "div", 2); system.out.println("#### first previous input ####"); system.out.println(firstprevinput.tostring()); system.out.println("##############################\n"); system.out.println("#### second previous div ####"); system.out.println(secprevdiv.tostring()); system.out.println("#############################\n"); system.out.println("#### second next div ####"); system.out.println(secnextdiv.tostring()); system.out.println("#########################");
output:
#### first previous input #### <input id="previousinput" name="communitymode" type="checkbox"> ############################## #### second previous div #### <div class="fl" style="margin-top: 8px; height: 24px;"> </div> ############################# #### second next div #### <div class="g-col -input"> <input id="nextinput" name="communitymode"> </div> #########################
Comments
Post a Comment