2013-06-27 4 views
0

잘못된 형식의 HTML을 구문 분석하기 위해 Jericho HTML Parser을 사용하고 있습니다. 특히 텍스트 노드를 모두 가져 와서 텍스트를 처리 한 다음 바꾸려고합니다.객체를 건너 뛰기 위해 반복자를 인덱스가있는 for 루프로 변환합니다.

가공에서 특정 요소를 건너 뛰고 싶습니다. 예를 들어, 모든 요소와 속성 class = "noProcess"가있는 요소는 건너 뜁니다. 따라서 div에 class = "noProcess"가있는 경우이 div와 모든 하위 항목을 건너 뛰고 싶습니다. 그러나, 나는 건너 뛴 이러한 요소를 처리 후에 출력으로 되돌리려 고합니다.

여리고는 모든 노드에 대해 반복기를 제공하지만 Iterator에서 전체 요소를 건너 뛰는 방법을 잘 모르겠습니다. 파서 그냥 텍스트로 "무시"요소를 취급로

private String doProcessHtml(String html) { 
     Source source = new Source(html); 
     OutputDocument outputDocument = new OutputDocument(source); 

     for (Segment segment : source) { 
      if (segment instanceof Tag) { 
       Tag tag = (Tag) segment; 
       System.out.println("FOUND TAG: " + tag.getName()); 

       // DO SOMETHING HERE TO SKIP ENTIRE ELEMENT IF IS <A> OR CLASS="noProcess" 

      } else if (segment instanceof CharacterReference) { 
       CharacterReference characterReference = (CharacterReference) segment; 
       System.out.println("FOUND CHARACTERREFERENCE: " + characterReference.getCharacterReferenceString()); 
      } else { 
       System.out.println("FOUND PLAIN TEXT: " + segment.toString()); 
       outputDocument.replace(segment, doProcessText(segment.toString())); 
      } 
     } 

     return outputDocument.toString(); 
    } 

그것은 ignoreWhenParsing() 메소드를 사용하여처럼 보이지 않는 나를 위해 작동합니다 : 여기 내 코드입니다.

내가 반복자 루프를 for (int i = 0; ...) 루프로 변환 할 수 있다면 나는 아마 EndTag를 가리 키도록 요소와 모든 자식을 건너 뛸 수있을 것이라고 생각했다. 루프를 계속합니다 ....하지만 확실하지 않습니다.

+0

'continue' 키워드는 어떻게 사용합니까? – sanbhat

+0

계속할 수는 있지만 다음 세그먼트는 건너 뛸 요소의 다음 하위 요소가됩니다. 그것이 작동하는 방식은 Iterator가 모든 세그먼트를 반환한다는 것입니다. 나는 말하고 싶은 것이있다 : 당신이 건너 뛰고 자하는 요소의 EndTag는 X 위치에있다. 그래서 X 위치로 건너 뛰고 계속 – user2287359

답변

0

이렇게하면됩니다.

String skipTag = null; 
for (Segment segment : source) { 
    if (skipTag != null) { // is skipping ON? 
     if (segment instanceof EndTag && // if EndTag found for the 
      skipTag.equals(((EndTag) segment).getName())) { // tag we're skipping 
      skipTag = null; // set skipping OFF 
     } 
     continue; // continue skipping (or skip the EndTag) 
    } else if (segment instanceof Tag) { // is tag? 
     Tag tag = (Tag) segment; 
     System.out.println("FOUND TAG: " + tag.getName()); 
     if (HTMLElementName.A.equals(tag.getName()) { // if <a> ? 
      skipTag = tag.getName(); // set 
      continue; // skipping ON 
     } else if (tag instanceof StartTag) { 
      if ("noProcess".equals(// if <tag class="noProcess" ..> ? 
        ((StartTag) tag).getAttributeValue("class"))) { 
       skipTag = tag.getName(); // set 
       continue; // skipping ON 
      } 
     } 
    } // ... 
} 
+0

continue는 그것을하지 않을 것이다. 전체 요소를 건너 뛰지는 않습니다. 그것은 단지 특정 Tag 객체를 건너 뜁니다. – user2287359

+0

@ user2287359 업데이트를 확인하십시오. –

0

세그먼트를 만드는 방식을 다시 고려해 볼 수 있습니다. 각 세그먼트가 자식 요소의 중첩 목록을 포함하는 부모 요소 인 방식으로 html을 구문 분석 할 수있는 방법이 있습니까? 당신은 같은 것을 할 수있는 그런 식으로 : 세그먼트 요소를 구조 조정하는 것도 가능 또는 노력이 가치가 있는지 더 많은 코드없이

for (Segment segment : source) { 
     if (segment instanceof Tag) { 
      Tag tag = (Tag) segment; 
      System.out.println("FOUND TAG: " + tag.getName()); 

      // DO SOMETHING HERE TO SKIP ENTIRE ELEMENT IF IS <A> OR CLASS="noProcess" 
      continue; 

     } else if (segment instanceof CharacterReference) { 
      CharacterReference characterReference = (CharacterReference) segment; 
      System.out.println("FOUND CHARACTERREFERENCE: " + characterReference.getCharacterReferenceString()); 
      for(Segment child : segment.childNodes()) { 
       //Use recursion to process child elements 
       //You will want to put your for loop in a separate method so it can be called recursively. 
      } 
     } else { 
      System.out.println("FOUND PLAIN TEXT: " + segment.toString()); 
      outputDocument.replace(segment, doProcessText(segment.toString())); 
     } 
    } 

결정하기 위해 하드를 검사합니다.

0

태그의 Element 객체에 대한 getEnd() 메서드를 사용하여 작업 솔루션을 관리 할 수 ​​있습니다. 아이디어는 끝 위치가 설정 한 위치보다 작 으면 요소를 건너 뜁니다. 따라서 제외하려는 요소의 끝 위치를 찾고 그 위치 이전에 다른 것을 처리하지 마십시오.