2012-10-09 3 views
1

$value이있는 xpaths를 나열하는 다음 코드가 있습니다.DOM에서 잘못된 요소를 제거하는 방법은 무엇입니까?

주어진 URL (폐쇄 형 태그가없는 이외의 표준 태그 td1)을 감지했습니다 (그림 참조). 아마도 사이트 개발자는 아래 스크린 샷에서 볼 수 있듯이 의도적으로 사이트 개발자를 배치했을 것입니다.

이 요소는 노드의 핵심 XPath를 식별하는 데 문제가 발생합니다.

깨진 된 XPath 예 :

/html/body/div[2]/div[2]/table/tr[2]/td/table/tr[1]/td[2]/table/tr[2]/td[2]/table[3]/tr[2]/**td1**/td[2]/span/u[1] 

우리가 뒤에있는 유효한 XPath를 구축하는 데 도움이 요소를 제거하여

우리는 생각한다 (당신이 TD1 식별하고는 XPath에 연결됩니다 참조로) .

유효한 예를 들어 우리가 DOMXpath에 사전로드를 제거하는 방법

/html/body/div[2]/div[2]/table/tr[2]/td/table/tr[1]/td[2]/table/tr[2]/td[2]/table[3]/tr[2]/td[2]/span/u[1] 

입니까? 다른 접근법이 있습니까?

우리는 TD1 이외 될 수있는 모든 잘못된 태그,

private function extract($url, $value) { 

     $dom = new DOMDocument(); 

     $file = 'content.txt'; 
     //$current = file_get_contents($url); 
     $current = CurlTool::downloadFile($url, $file); 
     //file_put_contents($file, $current); 

     @$dom->loadHTMLFile($current); 

     //use DOMXpath to navigate the html with the DOM 
     $dom_xpath = new DOMXpath($dom); 

     $elements = $dom_xpath->query("//*[text()[contains(., '" . $value . "')]]"); 
     var_dump($elements); 
     if (!is_null($elements)) { 

      foreach ($elements as $element) { 
       var_dump($element); 
       echo "\n1.[" . $element->nodeName . "]\n"; 

       $nodes = $element->childNodes; 
       foreach ($nodes as $node) { 
        if(($node->nodeValue != null) && ($node->nodeValue === $value)) { 
         echo '2.' . $node->nodeValue . "\n"; 
         $xpath = preg_replace("/\/text\(\)/", "", $node->getNodePath()); 
         echo '3.' . $xpath . "\n"; 
        } 
       } 
      } 
     } 
    } 
SOOO

enter image description here

+2

DOM 노드의 구문 분석기를 만드는 행운을 비 빕니다. Stackoverflow에 대한 다른 질문을 보면 잘못된 코드를 수정하기 위해 정규 표현식을 작성하는 것이 기본적으로 불가능하다는 것을 알 수 있습니다. – epascarello

+0

XPath의 경우 td1이 유효한 HTML 요소가 아니어도 상관 없습니다. http://codepad.org/eMKjNyXL을 참조하십시오 – Gordon

답변

1

XPath를 사용하여 문제의 노드를 찾아서 제거하고 DOM의 자식을 해당 위치로 승격시킬 수 있습니다. 그러면 경로가 정확합니다.

$dom_xpath = new DOMXpath($dom); 
$results = $dom_xpath->query('//td1'); // (or any offending element) 
foreach ($results as $invalidNode) 
{ 
    $parentNode = $invalidNode->parentNode; 
    while ($invalidNode->childNodes) 
    { 
     $firstChild = $invalidNode->firstChild; 
     $parentNode->insertBefore($firstChild,$invalidNode); 
    } 
    $parentNode->removeChild($invalidNode); 
} 

편집 :

또한 유효한 요소 목록을 사용하여 그것을 부정에 의해 일으키는 요소의 목록을 만들 수있다.

// Build list manually from the HTML spec: 
// See: http://www.w3.org/TR/html5/section-index.html#elements-1 
$validTags = array(); 

// Convert list to XPath: 
$validTagsStr = ''; 
foreach ($validTags as $tag) 
{ 
    if ($validTagsStr) 
    { $validTagsStr .= ' or '; } 
    $validTagsStr .= 'self::'.$tag; 
} 
$results = $dom_xpath->query('//*[not('.$validTagsStr.')'); 
+0

일 수 있습니다. 제가 깨진 태그를 알고 있다면 도움이 될 것입니다. 그러나 나는 그들을 모른다. –

+0

그러나 유효한 태그가있는 목록이 있으면 유용 할 수 있습니다. –

+0

다음은 목록입니다. http://www.w3.org/TR/html5/section-index.html#elements-1 목록에없는 XPath 절과 일치하는 XPath 절. – jimp

1

... 등 H8, DIW로 ... 아마도 str_replace($current, "<td1 va-laign=\"top\">", "")이 할 수있는을 제거 할 것 속임수?

+0

우리는 일반적인 해결책을 원합니다. 다음에 태그가 ,

관련 문제