2009-06-15 7 views
10

chcę przekonwertować DOMNode obiektu z wywołania getElementsByTagName() do DOMElement w celu metod dostępu jak getElementsByTagName() na element dziecięcej. W każdym innym języku rzuciłbym i byłoby to łatwe, ale po krótkim wyglądzie PHP nie ma rzutowania obiektów. Więc muszę wiedzieć, jak uzyskać obiekt DOMElement z obiektu .DOMNode do DOMElement w php

+0

Czy sprawdziłeś, czy getElementsByTagName() faktycznie zwraca obiekty DOMElement z czymś w rodzaju if ($ item instanceof DOMElement)? Jeśli nie musisz rzutować, możesz po prostu użyć elementu $ tak jak jest DOMElement – rojoca

+0

getElementsByTagName() zwraca DOMNodeList, założyłem, że lista DOMNodeList była listą DOMNode. Powodem, dla którego myślałem, że musisz rzucić, było to, że musiałem rzucić w Javę, gdy chciałem zrobić ten sam proces. – Samuel

+1

Zabawne jest to, że getElementById zwraca DOMElement, ale getElementsByTagName zwraca listę, w której każdy element jest DOMNode !! – Andrew

Odpowiedz

15

Nie trzeba rzucać niczego, po prostu wywołać metodę:

$links = $dom->getElementsByTagName('a'); 

foreach ($links as $link) { 
    $spans = $link->getElementsByTagName('span'); 
} 

A przy okazji, DOMElement jest podklasą DOMNode. Jakbyś mówił o DOMNodeList, wówczas dostępu do elementów w takiej listy można zrobić, to być albo sposób przedstawiony powyżej, z foreach() pętli, albo przy użyciu metody item() z DOMNodeList:

$link_0 = $dom->getElementsByTagName('a')->item(0); 
+0

Czy DOMNodeList kiedykolwiek zwróci DOMNode, który nie jest DOMElement? [The docs] (http://us3.php.net/manual/en/class.domnodelist.php) po prostu powiedz DOMNode i nie wspominaj o DOMElement. Na przykład, co jeśli katalog DOMNodeList pochodzi z zapytania [DOMXPath :: query] (http://us2.php.net/manual/en/domxpath.query.php)? – paulie4

+0

@ user2016290 tak, 'DOMXPath :: query' lub nawet' DOMNode :: childNodes'. https://gist.github.com/igstan/9654eca0db804c8e87bd –

+0

DOMElement ma dodatkowe metody, które nie są dostępne w DOMNode. Na przykład getAttribute().I chociaż jeśli użyjesz tej metody w domenie DOMNode, będzie działać w PHP, nie będzie działać z twoim IDE (niedostępne na liście metod wyskakujących). Więc pytanie brzmi: jak uzyskać DOMElement z getElementsByTagName – Andrew

1

don Trzeba wykonać wyraźne typowanie, po prostu sprawdź, czy twój obiekt DOMNode ma typ nodeType: XML_ELEMENT_NODE.

PHP będzie z tego całkowicie zadowolony.

Jeśli użyjesz PHPLint do sprawdzenia kodu, zauważysz, że PHPLint narzeka na używanie getElementsByTagName na obiekcie DOMNode. Aby obejść ten problem trzeba skakać przez obręcz następujący:

/*.object.*/ $obj = $node; 
$element = /*.(DOMElement).*/ $obj; 

Wtedy masz $ elementu zmienną odpowiedniego typu i żadnych skarg od PHPLint.

0

Wiem, że jest to głównie irytujący problem IDE.

Powód jest następujący: $DOMNodeList->item(0) zwraca DOMNode (lub przynajmniej IDE tak myśli).

Aby to naprawić, należy wyodrębnić $DOMDocument->getElementsByTagName($tagName)->item($index) w samodzielną metodę. W DOCBlock ustawiasz instrukcję @return na DOMElement witch, która naprawia problem z inspekcją.

To działa co najmniej w PHPStorm.

0

Tego używam w moim projekcie, aby zminimalizować ostrzeżenie IDE.

/** 
* Cast a DOMNode into a DOMElement 
*/ 
    function cast_e(DOMNode $node) : DOMElement { 
    if ($node) { 
     if ($node->nodeType === XML_ELEMENT_NODE) { 
      return $node; 
     } 
    } 
    return null; 
}