SimpleXML and PHP (XPATH) - php

Ok guys I'm using xml to store page information for a dynamic website. I need to figure out a way to take a variable(file name) and pull the related node and parse that information. so basically here's my XML structure...
<SITE>
<PAGE>
<FILENAME>sub.php</FILENAME>
<DESCRIPTION>this is an example sub page</DESCRIPTION>
<TITLE>NOH Sub page</TITLE>
<PARENTS>
<PARENT>What is NOH</PARENT>
</PARENTS>
</PAGE>
<PAGE>
<FILENAME>about.php</FILENAME>
<DESCRIPTION>description description description </DESCRIPTION>
<TITLE>About Us</TITLE>
<PARENTS>
<PARENT>Company</PARENT>
<PARENT>People</PARENT>
</PARENTS>
</PAGE>
</SITE>
Is there a way to use SimpleXML and PHP to take a variable say.. 'sub.php' and say I want the node where filename = 'sub.php', and then be able to parse that node(page) for needed info. Thanks!
Update, where I'm confused is...
i have this function
function getPage($pagePath){
$file = "includes/sitestructure.xml";
$xml = simplexml_load_file($file);
return print_r($xml-xpath(PAGE/FILENAME));
}
but my xpath doesn't work, and I'm not sure how to logically get the info I need.. I know how to normally parse XML with PHP but not how to specify a specific node by comparing it to a variable then parse it.

$xml-xpath(PAGE/FILENAME)
This is broken in several ways, but this is an XPath question not a PHP syntax one.
You want to get the PAGE element(s) which contain a FILENAME of your chosen file name. To do that in XPath, a predicate can be used.
PAGE[FILENAME="sub.php"]
In your PHP code that might look like
$pages = $xml->xpath('PAGE[FILENAME="sub.php"]');
$first_page = $pages[0];
echo $first_page->TITLE; // NOH Sub page
The important point here is the use of the predicate to filter the result to only the page element(s) that you want.
http://www.w3.org/TR/xpath/#predicates

Related

PHP/XML feed reader where to start?

I have a question regarding XML feeds.
There is a website whitch provides data and they give me 2 links for 2 files
file 1 : Cars_docu.atom
file 2 : Cars.atom
date on file 1 is like this
<entry>
<author>
<name />
</author>
<f:name>Name</f:name>
<f:description>Product name</f:description>
and the second file is like this
<entry>
<title>Volvo</title>
<link rel="alternate" href="#1" />
<author>
<name />
</author>
<id>237370</id>
<updated>2015-08-17T11:44:32Z</updated>
<f:name>Volvo Lamp</f:name>
So as I understand the first file includes name of the filds and the second one includes the data
My question is what is the method of pulling this imformation from both files using a PHP file and gather them into one page ?
and inside the second document there is a 10000 product so how i pull one pacific product only?
I need methods if you have code I will be glad or just tell me where to start
regads
Take a look at the SimpleXML Class:
http://php.net/manual/en/class.simplexmlelement.php
The approach to take is to use file_get_contents to pull the data from the XML pages and then use SimpleXML to parse it into an array.
For example:
<?php
$url = "somewebsite.com/Cars.atom";
$file = file_get_contents($url);
$carsArray = new SimpleXMLElement($file);
foreach ($carsArray->entry as $car) {
echo $car->title; // Would display "Volvo"
}
?>
When I'm first investigating the structure of an XML document that has been parsed into an array I find it useful to use the print_r() function.
From the above, the next simple step is to load both XML doc's and work you way through to build the data you want to display.
Edit if you want to match a specific item
Assuming you are wanting to match the car title to Volvo, this is how you could do it.
<?php
$url = "somewebsite.com/Cars.atom";
$file = file_get_contents($url);
$carsArray = new SimpleXMLElement($file);
// Need to use an array key to get the element, alternatively can loop through each value
if($carsArray->entry[0]->title == "Volvo") {
echo "Car is a Volvo!";
}
?>

Need some help in accessing an xml document to add/remove content

I am working with an XML document with the structure shown below and i am trying to add/remove image objects without having to treat the xml document as text. Each image object corresponds to a picture in the album.
<?xml version="1.0" encoding="UTF-8"?>
<gallery galleryTitle="Photo Album">
<image imageURL="../Photoalbum/artwork/eb98e388e14b11008d4ffb595b9ed3e6.jpg"
thumbURL="../Photoalbum/artwork/thumbs/tn_eb98e388e14b11008d4ffb595b9ed3e6.jpg"
linkURL="../Photoalbum/artwork/eb98e388e14b11008d4ffb595b9ed3e6.jpg"
linkTarget="_blank">
<title>A Title</title>
<caption>A caption</caption>
</image>
</gallery>
I have been able to access and print the xml file as a whole with the code below
if (file_exists('file.xml')) {
$xml = simplexml_load_file('file.xml');
print"<pre>";
print_r($xml);
}
but so far have not been able to access individual fields of the image object. The object that will be added/removed will be identified by a unique filename such as eb98e388e14b11008d4ffb595b9ed3e6.jpg so once this filename is found in the XML document, i want the whole image object removed. Similarly, i would like to be able to add a new image object with a new filename.
Let me know if my question is clear.
Use xpath() to select the <image>-node. xpath is like SQL for XML:
$image = $xml->xpath("/gallery/image[contains(#imageURL, $filename)]");
... and unset() to remove that node:
if (isset($image[0])) unset($image[0][0]);
see it working: https://eval.in/135145
use the search-function to see how to add a new <image> with SimpleXml.

Zend Framework: Navigation XML and duplicate page elements

In XML I'd normal expect the following to be perfectly valid and navigable in a meaningful way using something like PHP's DomDocument:
<?xml version="1.0" encoding="UTF-8"?>
<configdata>
<page>
<name>Home</name>
</page>
<page>
<name>Log in</name>
</page>
</configdata>
This is not the case when using Zend_Navigation. Each <page> element needs to have a unique name, so you would need to do:
<?xml version="1.0" encoding="UTF-8"?>
<configdata>
<page_home>
<name>Home</name>
</page_home>
<page_log_in>
<name>Log in</name>
</page_log_in>
</configdata>
This works, but is very annoying. I'd much rather have multiple page elements which can have the same name and can be easily copy and pasted when creating many pages for navigation.
Why does each one need a unique name?
Is there a way of not having to have a unique name?
#Charles
Yes, the following code is used to read in the navigaion XML
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml');
$container = new Zend_Navigation($config);
Zend_Registry::set("navigation", $container);
#Gordon
Good question...I used to use this method, but wanted another way that was easier to update and read. The array notation does solve the issue I have but it isn't an easy way of writing out the navigation for a site, especially when there are nested elements. XML is much easy to read and make sense of than PHP's arrays.
Granted this is my own opinion and it is a slower way of storing and parsing navigation data.
You can't use the first XML structure, because Zend_Navigation uses the Tag definition to create a part of the "Route". If you want use an another type of XML structure, you probably have to extend Zend_Navigation with your own parsing process.
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml');
$container new My_Navigation($config);
Another way would be to create a class to parse and modify the XML document before sending it to Zend_Navigation.
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml');
$navigationStructure = new My_Navigation_Parser($config);
$container new My_Navigation($navigationStructure);

How do I add new elements to XML using PHP DOM deeper than the root?

All of the examples I can find online about this involve simply adding content to an XML file at the document root, but I really need to do it deeper than that.
My XML file is simple, I have:
<?xml v1 etc>
<channel>
<screenshots>
<item>
<title>Image Title</title>
<link>www.link.com/image.jpg</link>
</item>
</screenshots>
</channel>
All I want to be able to do is add new "item" elements, each with a title and link. I know I need to be using PHP DOM, but I'm stumped as to how to code it so that it adds data within "screenshots" rather than overwriting the whole document. I have a suspicion I may need to use XPath too, but I have no idea how!
The code I have pieced together from online examples looks like this (but I'm certain it's wrong)
$newshottitle = "My new screenshot";
$newshotlink = "http://www.image.com/image.jpg";
$dom = newDomDocument;
$dom->formatOutput = true;
$dom->load("../xml/screenshots.xml");
$dom->getElementsByTagName("screenshots");
$t = $dom->createElement("item");
$t = $dom->createElement("title");
$t->appendChild($dom->createTextNode("$newshottitle"));
$l = $dom->createElement("link");
$l->appendChild($dom->createTextNode("$newshotlink"));
$dom->save("../xml/screenshots.xml");
adding content to an XML file at the document root, but I really need to do it deeper than that.
You're not adding content anywhere at the moment! You create <title> and <link> element nodes with text in, then you do nothing with them. You should be passing them into ‘appendChild’ on the <item> element node (which also you are currently creating and immediately throwing away by not assigning it to a variable).
Here's a starting-point:
$screenshots= $dom->getElementsByTagName("screenshots")[0];
$title= $dom->createElement("title");
$title->appendChild($dom->createTextNode($newshottitle));
$item= $dom->createElement("item");
$item->appendChild($title);
$screenshots->appendChild($item);

What php function can display formated XHTML from a XML file?

Ive been trying to display formatted content blocks from a xml file with no luck. Ive been using simplexml_load_file and other varients which Im now seeing cannot deal with the xhtml tags within the called tag ... eg.
//php contents
<?php $xml=simplexml_load_file("file.xml");
echo ($xml->entry); ?>
//xml contents
<entry>
<p>This does not work</p>
</entry>
whereas
<entry>This works</entry>
can someone please tell me which php function can do this from an xml file and or
what is the best way to display the contents with xhtml formatting?
Im trying to dynamically load content to a webpage without having to build too many pages. I like the idea of having all my content in one xml file for easy edits.
Theres not enough content to justify a database yet.
Thanks in advance
You can try dumping the contents of a certain simplexml node (in this case: $xml->entry) using the asXml function.
echo $xml->entry->asXml();
Check the php documentation on simplexml here (link to the asXml() call):
Simplexml documentation
im getting closer... I found asXML() which outputs the html tags... but not sure yet how to point to specific blocks.... eg $xml->asXML(block) displays 1
got it
$xml->block->asXML()
works
would still like to know if there is a better method tho.

Categories