DOMDocument
在线手册:中文  英文

DOMDocument::getElementsByTagName

(PHP 5)

DOMDocument::getElementsByTagNameSearches for all elements with given local tag name

说明

public DOMNodeList DOMDocument::getElementsByTagName ( string $name )

This function returns a new instance of class DOMNodeList containing all the elements with a given local tag name.

参数

name

The local name (without namespace) of the tag to match on. The special value * matches all tags.

返回值

A new DOMNodeList object containing all the matched elements.

范例

Example #1 Basic Usage Example

<?php
$xml 
= <<< XML
<?xml version="1.0" encoding="utf-8"?>
<books>
 <book>Patterns of Enterprise Application Architecture</book>
 <book>Design Patterns: Elements of Reusable Software Design</book>
 <book>Clean Code</book>
</books>
XML;

$dom = new DOMDocument;
$dom->loadXML($xml);
$books $dom->getElementsByTagName('book');
foreach (
$books as $book) {
    echo 
$book->nodeValuePHP_EOL;
}
?>

以上例程会输出:

Patterns of Enterprise Application Architecture
Design Patterns: Elements of Reusable Software Design
Clean Code

参见


DOMDocument
在线手册:中文  英文

用户评论:

yaakov dot moddel at gmail dot com (2012-08-28 22:47:11)

This is a very simplistic way to traverse xml nodes and childnodes using the DOMDocument class

<?php
$xml 
='<?xml version="1.0" encoding="utf-8"?>
<root>
    <Parent>
        <child>child 1</child>
        <child>child 2</child>
        <child>child 3</child>
        <subParent>
            <Grandchild>Grandchild 1</Grandchild>
            <Grandchild>Grandchild 2</Grandchild>
            <Grandchild>Grandchild 3</Grandchild>
        </subParent>
    </Parent>
    <Parent>
        <child>child 4</child>
        <child>child 5</child>
        <child>child 6</child>
        <subParent>
            <Grandchild>Grandchild 4</Grandchild>
            <Grandchild>Grandchild 5</Grandchild>
            <Grandchild>Grandchild 6</Grandchild>
        </subParent>
    </Parent>
</root>'
;
      
$doc = new DOMDocument();
      
$doc->preserveWhiteSpace false;
      
$doc->loadXML($xml);
      
$i=0;
            while(
is_object($finance $doc->getElementsByTagName("Parent")->item($i)))
            {
                     foreach(
$finance->childNodes as $nodename)
                     {
                             if(
$nodename->nodeName=='subParent')
                                {
                                     foreach(
$nodename->childNodes as $subNodes)
                                     {
                                     echo 
$subNodes->nodeName." - ".$subNodes->nodeValue."<br>";
                                     }
                                }
                             else
                                {
                                echo 
$nodename->nodeName." - ".$nodename->nodeValue."<br>";
                                }
                     }
      
$i++;
            }
?>

metron at underhive-planet dot com (2010-10-08 05:28:12)

My first try to get a stable solution with this function, failed with this Exception:

"Fatal error: Call to undefined method DOMNodeList::getElementsByTagName()"
This is the xml snipplet:
<?xml version="1.0" encoding="UTF-8"?>
<root>
 <component>
  <properties>
    ....<any element>
  </properties>
 </component>
</root>

So the php code to climb along the elements is:
<?php 

$src 
= new DOMDocument('1.0''utf-8');
$src->formatOutput true;
$src->preserveWhiteSpace false;

//Loading extern file
$src->load('../xml/Item_component.xml');

//Check each child of first indexed branch node of: <component>
//First get element after root element: <component>

//1st level
$component $src->getElementsByTagName('component')->item(0);

//2nd level, get next element after component, here it fails!!
$properties $component->getElementsByTagName('properties')->item(0);
...
?>

I realised, that there is a different when using different libxml2 versions on Apache2. This code will fail with libxml2 version 2.6.23 and PHP version 5.2.6
--
->It works fine with libxml2 version 2.6.32 and PHP version 5.2.6-3ubuntu4.6
->...and finally it also works with libxml2 2.7.7 and PHP >= 5.3

So if you bored to search for solutions with DOM like I did, please ensure that your www environment has the correct libxml2 / PHP Version installed on your apache2 server.

calvin at g mail (2010-10-02 16:41:07)

My first post!
And this is how I get elements by attribute and its value.
For an example, if I want to grab all DIV tags with class name 'className', then...

<?php
$some_link 
'some website';
$tagName 'div';
$attrName 'class';
$attrValue 'className';

$dom = new DOMDocument;
$dom->preserveWhiteSpace false;
@
$dom->loadHTMLFile($some_link);

$html getTags$dom$tagName$attrName$attrValue );
echo 
$html;

function 
getTags$dom$tagName$attrName$attrValue ){
    
$html '';
    
$domxpath = new DOMXPath($dom);
    
$newDom = new DOMDocument;
    
$newDom->formatOutput true;

    
$filtered $domxpath->query("//$tagName'[@' $attrName "='$attrValue']");
    
// $filtered =  $domxpath->query('//div[@class="className"]');
    // '//' when you don't know 'absolute' path

    // since above returns DomNodeList Object
    // I use following routine to convert it to string(html); copied it from someone's post in this site. Thank you.
    
$i 0;
    while( 
$myItem $filtered->item($i++) ){
        
$node $newDom->importNode$myItemtrue );    // import node
        
$newDom->appendChild($node);                    // append node
    
}
    
$html $newDom->saveHTML();
    return 
$html;
}

?>

Please, improve it, and share it.

Philip N (2010-09-01 03:17:19)

Note that when using getElementsByTagName that it is a dynamic list. Thus if you have code which adjusts the DOM structure it will change the results of the getElementsByTagName results list.

The following code iterates through a complete set of results and changes them all to a new tag:

<?php
 $nodes 
$xml->getElementsByTagName ("oldtag");

 
$nodeListLength $nodes->length// this value will also change
 
for ($i 0$i $nodeListLength$i ++)
 {
    
$node $nodes->item(0);

    
// some code to change the tag name from "oldtag" to something else
    // e.g. encrypting a tag element
 
}
?>

Since the list is dynamically updating, $nodes->item(0) is the next "unchanged" tag.

Marco Maranao (2010-04-27 22:22:45)

The following takes a list of news items from an XML file (or an RSS feed), assigning it to an array first for a name value pair and then generating an HTML list.

<?php

$xml  
=<<<EOT
<?xml version="1.0" encoding="ISO-8859-1"?>
<news>
    <item>
        <title>News 1</title>
        <created>04/2/2010 08:00 EST</created>
        <url>http://news.example.com/news.pdf</url>
    </item>
    <item>
        <title>News 2</title>
        <created>04/25/2010 08:00 EST</created>
        <url>http://news.example.com/news.pdf</url>
    </item>
    <item>
        <title>News 3</title>
        <created>04/27/2010 08:00 EST</created>
        <url>http://news.example.com/news.pdf</url>
    </item>
</news>
EOT;

$doc = new DOMDocument();

if (
$doc->loadXML($xml)) {
    
$items $doc->getElementsByTagName('item');
    
$headlines = array();
    
    foreach(
$items as $item) {
        
$headline = array();
        
        if(
$item->childNodes->length) {
            foreach(
$item->childNodes as $i) {
                
$headline[$i->nodeName] = $i->nodeValue;
            }
        }
        
        
$headlines[] = $headline;
    }
    
    if(!empty(
$headlines)) {
        
$hc 0;
        
        echo 
'<ul>';
        
        foreach(
$headlines as $headline) {
            if(++
$hc <= 3) {
                echo 
'<li>'
                    
.'<a href="'.$headline['url'].'" target="_blank">'
                        
.'<span>'.date('F j, Y'strtotime($headline['created'])).'</span><br />'
                        
.$headline['title']
                    .
'</a>'
                
.'</li>';
            }
        }
        
        echo 
'</ul>';
    }
}

?>

james (2010-02-01 19:03:00)

Problem:
You have an XML document that contains filename references to, say, images. Each filename reference is defined by <file>filename.ext</file> tag. You'd like to perform perform additional validation, say, after running the XML document through XSD validation. The additional validation can be any of your choice, in this example, it would be ideal to convert the PHP code to a function. The function would then determine if the images exist and return either an integer value or a boolean.

<?xml version="1.0"?>
<root>
<box>
<file>example.png</file>
</box>
<content>
<item>
<image><file>example2.png</file></image>
<caption>The above image is an example</caption>
</item>
</content>
</root>

Solution:
<?php

$dom 
= new DomDocument();
$dom->prevservWhiteSpace false;

if (!@
$dom->load("example.xml")) {
    echo 
"example.xml doesn't exist!\n";
    return;
}

$imageList $dom->getElementsByTagName('file');
$imageCnt  $imageList->length;

for (
$idx 0$idx $imageCnt$idx++) {
    print 
$imageList->item($idx)->nodeValue "\n";
}

?>

The above PHP code could easily be turned into a function that returns an array of image filenames, an integer value relative to the number of images found, etc.

Hope this is helpful.

gurmukh24 at gmail dot com (2009-03-03 04:06:22)

Following Example is of multiple attributes and multiple child nodes. this is being used to make joomla plugin for bulk upload of articles. Gurmukh Singh Bhatti

<?php
$xml 
=<<<EOT
<?xml version="1.0"?>
<root>
<section name="Section1">
  <category id="Category1" name="google">
   <arti name="article1">
   <p>any html code here</p>
   <b>my name is so so</b>
    </arti>
   <arti name="article2">value2</arti>
   <arti name="article3">value3</arti>
   <arti name="article4">value4</arti>
  </category>
    <category id="Category2" name="yahoo">
   <arti name="articleSection2">Test value</arti>
  </category>
</section>
<section name="Section2">
  <category id="category1_of_section2" name="msn">
   <arti name="article2">value1</arti>
   <arti name="article3">value2</arti>
  </category>
    <category id="Category2_of_section2" name="webcare">
    <arti name="param3">value4</arti>
   </category>
</section>
</root>
EOT;

$dom = new DomDocument;
$dom->preserveWhiteSpace FALSE;
$dom->loadXML($xml);
$params $dom->getElementsByTagName('section'); // Find Sections 
$k=0;
foreach (
$params as $param//go to each section 1 by 1 
{
         echo 
"Section Attribute :-> ".$params->item($k)->getAttribute('name')."<br>";   //get section attribute            
         
$params2 $params->item($k)->getElementsByTagName('category'); //digg categories with in Section
      
$i=0// values is used to iterate categories  
        
foreach ($params2 as $p) {
           echo 
"&nbsp;&nbsp;- Category Attribute Name :-> ".$params2->item($i)->getAttribute('name')."<br>"//get Category attributes
            
$params3 $params2->item($i)->getElementsByTagName('arti'); //dig Arti into Categories
                 
$j=0;//values used to interate Arti
                     
foreach ($params3 as $p2)
                   {
                    echo 
"&nbsp;&nbsp;&nbsp;- Article Attribute Name : ".$params3->item($j)->getAttribute('name').""//get arti atributes
echo "&nbsp;&nbsp; Value : ".$params3->item($j)->nodeValue."<br>"//get Node value ;
                              
$j++;   
                   }              
         
$i++;
      }
$k++;    
          
}
?>

output :
 Section Attribute :-> Section1
  - Category Attribute Name :-> google
            - Article Attribute Name : article1   Value : any html code heremy name is so so
            - Article Attribute Name : article2   Value : value2
            - Article Attribute Name : article3   Value : value3
            - Article Attribute Name : article4   Value : value4
  - Category Attribute Name :-> yahoo
            - Article Attribute Name : articleSection2   Value : Test value
Section Attribute :-> Section2
  - Category Attribute Name :-> msn
            - Article Attribute Name : article2   Value : value1
            - Article Attribute Name : article3   Value : value2
  - Category Attribute Name :-> webcare
            - Article Attribute Name : param3   Value : value4

StudioAMK.com (2008-10-09 20:09:03)

<?php

$doc 
= new DOMDocument();
$doc->load'Users.xml' );
  
$dataset $doc->getElementsByTagName"dataUser" );
foreach( 
$dataset as $row )
{
    
$xmlUserNames $row->getElementsByTagName"UserName" );
    
$xmlUserName $xmlUserNames->item(0)->nodeValue;
  
    
$xmlEmails $row->getElementsByTagName"Email" );
    
$xmlEmail $xmlEmails->item(0)->nodeValue;
  
    
$xmlDisplayNames $row->getElementsByTagName"DisplayName" );
    
$xmlDisplayName $xmlDisplayNames->item(0)->nodeValue;
  
    echo 
"$xmlUserName - $xmlEmail - $xmlDisplayName\n"
}
?>

Contents in Users.xml

<NewDataSet> 
    <dataUser> 
        <UserName>StudioAMK</UserName> 
        <Email>user1@mail.com</Email> 
        <DisplayName>StudioAMK.com</DisplayName> 
    </dataUser> 
    <dataUser> 
        <UserName>User2</UserName> 
        <Email>user2@mail.com</Email> 
        <DisplayName>UserTwo</DisplayName> 
    </dataUser> 
</NewDataSet>

James L (2008-08-19 04:04:35)

Return if there are no matches is an empty DOMNodeList. Check using length property, e.g.:

<?php
$nodes
=$domDocument->getElementsByTagName('book') ; 
if (
$nodes->length==0) {
   
// no results
}
?>

jason at shaped dot ca (2008-02-11 04:59:47)

in response to tildy at pr dot hu
my preferred way is (in example to gather country data from an iso 3166 xml flie)
$countries = new DOMDocument();
$countries->load("./lib/iso_3166.xml");
$countriesList = $countries->getElementsByTagName("ISO_3166-1_Entry");
foreach($countriesList as $country) {
$values = $country->getElementsByTagName("*");
foreach($values as $node) {
echo $node->nodeName."=".$node->nodeValue;
}
}

tildy at pr dot hu (2007-12-13 04:51:45)

If you want to list the nodename and value of one item(node) this is an example:
$itemnodes = $doc->getElementsByTagName( "item" );
$nodes = $itemnodes->item(0)->getElementsByTagName( "*" );
for ( $i = 0; $i < $nodes->length; $i++ ) {
print "nodename=".$nodes->item( $i )->nodeName;
print "\t";
print "nodevalue : ".$nodes->item( $i )->nodeValue;
print "\r\n";
}
It will be list all children name and value of item.

Francois Hill (2007-07-30 07:36:59)

Careful : getElementsByTagName will yield all elements with the given tag name under the present node, at any sub-level (i.e. among child nodes and all other descendant nodes)

Finding values of a node (2007-03-14 02:01:08)

I don't know if this is that obvious but it was not for me, so in addition to gem at rellim dot com's posting:
adding 

<?php
echo $param -> nodeValue.'<br>';
?>

to the loop will output
value1
value2
value3

gem at rellim dot com (2004-09-29 16:20:10)

Here is an example of getElementsByTagName():

<?php
$xml 
=<<<EOT
<?xml version="1.0"?>
<config>
  <section id="section1">
   <param name="param1">value1</param>
   <param name="param2">value2</param>
  </section>
  <section id="section2">
   <param name="param3">value3</param>
  </section>
</config>
EOT;

$dom = new DomDocument;
$dom->preserveWhiteSpace FALSE;
$dom->loadXML($xml);
$params $dom->getElementsByTagName('param');

foreach (
$params as $param) {
       echo 
$param -> getAttribute('name').'<br>';
}
?>

Expected result:
--------------
param1
param2
param3

易百教程