I have a list, consisting of links looking like this:
<a href=index.php?p=page_1>Page 1</a>
<a href=index.php?p=page_2>Page 2</a>
<a href=index.php?p=page_3>Page 3</a>
When clicked they include a page (page_1.inc.php or page_2.inc.php or page_3.inc.php) on my page thanks to this script:
<?php
$pages_dir = 'pages';
if(!empty($_GET['p'])){
$pages = scandir($pages_dir, 0);
unset($pages[0], $pages[1]);
$p = $_GET['p'];
if (in_array($p.'.inc.php', $pages)){
include ($pages_dir.'/'.$p.'.inc.php');
}
else {
echo 'Sorry, could not find the page!';
}
}
else {
include($pages_dir.'/home.inc.php');
}
?>
Period.
I also have an xml file looking like this:
<program>
<item>
<date>27/8</date>
<title>Page 1</title>
<info>This is info text</info>
</item>
<item>
<date>3/9</date>
<title>Page 2</title>
<info>This is info text again</info>
</item>
<item>
<date>10/9</date>
<title>Page 3</title>
<info>This just some info</info>
</item>
</program>
This is what I want to achieve:
If I click on the link "Page 1" it will display "This is info text" on the page.
If I click on the link "Page 2" it will display "This is info text again" on the page.
If I click on the link "Page 3" it will display "This just some info" on the page.
Was I clear enough?
Is there any solution for this?
You should be able to do this with SimpleXMLElement using the xpath() method.
$xmlString = file_get_contents("path/to/xml/file.xml");
$xml = new SimpleXMLElement($xmlString);
$info = $xml->xpath("/program/item[title='Page " . $page . "']/info");
echo (string) $info[0];
Update:
To get an array of all dates you would do something like this:
$xmlString = file_get_contents("path/to/xml/file.xml");
$xml = new SimpleXMLElement($xmlString);
$results = $xml->xpath("/program/item/date");
$dates = array();
if (!empty($results)) {
foreach ($results as $date) {
array_push($dates, (string) $date); // It's important to typecast from SimpleXMLElement to string here
}
}
Also, you could combine the logic, if needed, from the first and second examples. You can reuse the $xml object for multiple XPath queries.
If you need $dates to be unique, you can either add an in_array() check before doing the array_push() or you can use array_unique() after the foreach.
Related
I've already read those topics:
PHP library for parsing XML with a colons in tag names? and
Simple XML - Dealing With Colons In Nodes but i coundt implement those solutions.
<item>
<title> TITLE </title>
<itunes:author> AUTHOR </itunes:author>
<description> TEST </description>
<itunes:subtitle> TEST </itunes:subtitle>
<itunes:summary> TEST </itunes:summary>
<itunes:image href="yoyoyoyo.jpg"/>
<pubDate> YESTERDAY </pubDate>
<itunes:block>no</itunes:block>
<itunes:explicit>no</itunes:explicit>
<itunes:duration>99:99:99</itunes:duration>
<itunes:keywords>key, words</itunes:keywords>
</item>
I want to get only itunes:duration and itunes:image. Here is my code:
$result = simplexml_load_file("http://blablabla.com/feed.xml");
$items = $result->xpath("//item");
foreach ($items as $item) {
echo $item->title;
echo $item->pubDate;
}
I tried using children() method but when i try to print_r it it says that the node no longer exists.
You should use the children() on the $item element to get it's child-elements:
$str =<<< END
<item>
<title> TITLE </title>
<itunes:author> AUTHOR </itunes:author>
<description> TEST </description>
<itunes:subtitle> TEST </itunes:subtitle>
<itunes:summary> TEST </itunes:summary>
<itunes:image href="yoyoyoyo.jpg"/>
<pubDate> YESTERDAY </pubDate>
<itunes:block>no</itunes:block>
<itunes:explicit>no</itunes:explicit>
<itunes:duration>99:99:99</itunes:duration>
<itunes:keywords>key, words</itunes:keywords>
</item>
END;
$result = #simplexml_load_string($str);
$items = $result->xpath("//item");
foreach ($items as $item) {
echo $item->title . "\n";
echo $item->pubDate . "\n";
echo $item->children()->{'itunes:duration'} . "\n";
}
Output:
TITLE
YESTERDAY
99:99:99
Here goes my alternative solution if Dekel's dont work for someone.
Using method getNamespaces
$result = simplexml_load_file("http://blablabla.com/feed.xml");
$items = $result->xpath("//item");
foreach ($items as $item)
{
$itunesSpace = $item->getNameSpaces(true);
$nodes = $item->children($itunesSpace['itunes']);
//TEST
echo $nodes->subtitle
//99:99:99
echo $nodes->duration
//If you want the image Href
$imageAux = $nodes->image->attributes();
//yoyoyoyo.jpg
echo $imageAux['href'];
}
I need to display only the image from the CDATA content.
<item>
<title>... </title>
<link>... </link>
<description>... </description>
<category>... </category>
<pubDate>... </pubDate>
<guid>... </guid>
<content:encoded><![CDATA[<img alt="" src="..."/>...]]></content:encoded>
<enclosure url="..." type="image/jpeg" length="171228"></enclosure>
</item>
my code i tried looks like this an works fine for the part
<?php
$html = "";
$url = "http://www....";
$xml = simplexml_load_file($url);
for($i = 0; $i < 1; $i++){
//works fine with <description> part
$description = $xml->channel->item[$i]->description;
preg_match("/<img[^>]+\>/i", $description, $matches);
if (isset($matches[0])) {
$html .= $matches[0];
//echo "<br/>show img<br/>";
} else {
$html .= $description;
echo "<br/>there is no img";
}
}
echo $html;
?>
now i need a method for the part and show the image separately.
can someone help me fix this?
maybe it is possible to use the url in to display the image.
This is part of the xml:
<?xml version="1.0"?>
<menu>
<pizzas>
<pizza number="0">
<title>Tomato & Cheese</title>
<small>550</small>
<medium></medium>
<large>975</large>
</pizza>
PHP:
<?php
session_start();
?>
<div id="basket">
<h3 style="text-align:center; position:static;">Your Order:</h3>
<?php
$numberSelected = '';
$_SESSION['link'] = $numberSelected;
class dom{}
$dom = new dom;
$dom = simplexml_load_file("../../menu.xml");
foreach ($dom->xpath("/menu/*/*") as $item)
{
print $item->title;
}
print_r($_SESSION);
?>
</div>
How can I print the title of the pizza/item using the number stored in the $numberSelected variable?
I somehow need to access the value inside the <title></title> tag, which is inside its parent e.g. <pizza number="x">, where x comes from the variable $numberSelected.
You can just select the node where its attribute is using = thru xpath also:
[#number='$numberSelected']
So just query it and continue on getting the results if it did yielded. Use foreach if you're expecting more:
$result = $dom->xpath("//pizza[#number='$numberSelected']");
if(!empty($result)) {
$pizza = $result[0];
echo $pizza->title; // and others
}
Sample Output
The xml data looks like this:
<feed>
<entry>
<abc:rank scheme="http://foo.bar">45</abc:rank>
<abc:rank scheme="http://foo2.bar">88</abc:rank>
</entry>
<entry>
<abc:rank scheme="http://foo.bar">125</abc:rank>
<abc:rank scheme="http://foo2.bar">32</abc:rank>
</entry>
</feed>
I am able to output all of these entries with this code:
foreach($xml->entry[$i]->children('abc', true) as $a) {
echo $a;
}
However, if I want to get the one with the content "88" in the first entry, something like
foreach($xml->entry[$i]->children('abc', true) as $a) {
if($a["scheme"] == "http://foo2.bar")
echo $a;
}
does not work.
How can I select these children depending on their attribute?
Ok I got it by now. For those interested in the correct solution:
$namespaces = $xml->entry[$i]->getNameSpaces('true');
$abc= $xml->entry[$i]->children($namespaces['abc']);
foreach($abc->rank as $a) {
$scheme = $a->attributes();
echo $scheme['scheme'];
echo " - ";
}
I'm parsing an external Atom feed, some entries have a collection of namespaced children - I'm failing to retrieve attributes from those children. Abbreviated example:
$feed = <<<EOD
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:ai="http://activeinterface.com/thincms/2012">
<entry>
<title>Some Title</title>
<ai:image>path/to/some/image</ai:image>
<ai:ocurrence dateid="20120622" date="Fri, June 22, 2012" time="6:00 pm" />
<ai:ocurrence dateid="20120720" date="Fri, July 20, 2012" time="6:00 pm" />
</entry>
</feed>
EOD;
$xml = new SimpleXmlElement($feed);
foreach ($xml->entry as $entry){
echo $entry->title;
$namespaces = $entry->getNameSpaces(true);
$ai = $entry->children($namespaces['ai']);
echo $ai->image;
foreach($ai->ocurrence as $o){
echo $o['date'];
}
}
Everything but the attribute retrieval of the namespaced children works fine - if the children's tagnames aren't namespaced, it works fine. If grabbing the node value (rather than an attribute), even if namespaced, it works fine. What am I missing?
Try this
$xml = new SimpleXmlElement($feed);
foreach ($xml->entry as $entry)
{
$namespaces = $entry->getNameSpaces(true);
$ai = $entry->children($namespaces['ai']);
foreach ($ai->ocurrence as $o)
{
$date=$o->attributes();
echo $date['date'];
echo "<br/>";
}
}
don't know why, but apparently array access won't work here... need the attributes method:
echo $o->attributes()->date;