Sharon Moore
Sharon Moore

Reputation: 1

Parse XML with XPath In PHP

I need to echo only ID and title , I have used Xpath with xml to get the details ... I need to echo the ID and title for each in a seperate line ...

<?php
$xml = <<< XML
<data>
    <metadata>
        <total_elements>183</total_elements>
        <elements_per_page>100</elements_per_page>
        <total_pages>2</total_pages>
    </metadata>
    <spl>
        <id>ID1</id>
        <version>2</version>
        <title>Title 1</title>
        <published_date>Oct 06, 2017</published_date>
    </spl>
    <spl>
        <id>ID2</id>
        <version>2</version>
        <title>Title 2</title>
        <published_date>Oct 05, 2017</published_date>
    </spl>
    <spl>
        <id>ID3</id>
        <version>2</version>
        <title>Title 3</title>
        <published_date>Oct 04, 2017</published_date>
    </spl>
</data>
XML;

$errorSetting = libxml_use_internal_errors(TRUE);
$feed = new DOMDocument();
$feed->loadXML($xml);
libxml_clear_errors();
libxml_use_internal_errors($errorSetting);

$xpath = new DOMXPath($feed);

foreach ($xpath->query('//spl') as $spl) {
    foreach ($spl->childNodes as $child) 
    {
        if (($child->nodeValue) !== '') 
        {
            echo \htmlspecialchars($child->nodeValue);

        }
    }
}
?>

This Gives Output :

ID1
2
Title 1
Oct 06, 2017

ID2
2
Title 2
Oct 05, 2017

ID3
2
Title 3
Oct 04, 2017

Alternatively I tried :

foreach ($xpath->query('//id') as $id) 
    {
        if (($id->nodeValue) !== '') {
         echo \htmlspecialchars($id->nodeValue);                
        }
    foreach ($xpath->query('//title') as $title) { 
        echo \htmlspecialchars($title->nodeValue); 
        }

    }

But It gave Output as :

ID1 Title 1 Title 2 Title 3
ID2 Title 1 Title 2 Title 3
ID3 Title 1 Title 2 Title 3

I need Output as :

ID1 Title 1
ID2 Title 2
ID3 Title 3

Upvotes: 0

Views: 61

Answers (1)

Nigel Ren
Nigel Ren

Reputation: 57131

If you change your foreach loop to

foreach ($xpath->query('//spl') as $spl) {
    echo $xpath->evaluate("string(descendant::id/text())", $spl);
    echo $xpath->evaluate("string(descendant::title/text())", $spl);
    echo PHP_EOL;
}

This loops over all of the spl elements, then the inner XPath, fetches the id and title (descendant ensures it's only the items in the enclosing element). Using evaluate() means that rather than fetching a node, in this case, the value returned is a string. Also in evaluate() I'm using $spl as the start point for the query.

Upvotes: 2

Related Questions