Zend Framework: Navigation XML and duplicate page elements - php

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);

Related

Get information from a form and writing to an xml file using php?

I want to get information from a form and writing to an xml file by using php ? My xml file is in tree structure
Example of my xml file:
<BookStore>
<Book>
<name>TODO</name>
<url>TODO</url>
</Book>
</BookStore>
when I submit it will create a xml but I want Book and BookStore also as a parent. I created till name and url. But I dont know how to create Book and BookStore too?
You just need to create new parent elements and then append the child.
$bookstore = $doc->createElement('Bookstore');
$book = $doc->createElement("Book");
/* your code */
/* append name and url to $book */
$book->appendChild($textareaNode);
$book->appendChild($textareaNode1);
$bookstore->appendChild($book);
$doc->appendChild($bookstore);
$doc->save("d.xml");

Using DOMDocument PHP classes on simple XML file

My XML document is as follows.
<?xml version="1.0" encoding="utf-8"?>
<userSettings>
<tables>
<table id="supertable">
<userTabLayout id="A">{"id":"colidgoeshereX"}</userTabLayout>
<userTabLayout id="B">{"id":"colidgoeshereY"}</userTabLayout>
</table>
<table id="almost-supertable">
<userTabLayout id="A">{"id":"colidgoeshereC"}</userTabLayout>
<userTabLayout id="B">{"id":"colidgoeshereD"}</userTabLayout>
</table>
</tables>
</userSettings>
I'm using the following PHP code to load the file (DOMDocument) and then DomXpath to traverse the document
<?php
...
$xmldoc = new DOMDocument();
$xmldoc->load ($filename);
$xpath = new DomXpath($xmldoc);
$x = $xpath->query("//tables/table");
$y = $x->item(0);
...
?>
The $y variable now contains a DOMElement object, with a nodeValue attribute containing the string as follows:
["nodeValue"]=>
string(81) "
{"id":"colidgoeshereX"}
{"id":"colidgoeshereY"}
"
My question is, what happened to the <userTabLayout> node? Why do I not see this as a child node to the <table> node? And if I wanted to access the <userTabLayout id="B"> node, how would I do that?
Normally I'd read the documentation on this kind of stuff, but the official documentation on the official PHP page, is really sparse.
My question is, what happened to the <userTabLayout> node?
Nothing happened to it. The <userTabLayout> elements are child-elements of the DOMElement you have in $y.
Why do I not see this as a child node to the <table> node?
Because you're not looking for child-nodes by using the nodeValue field.
And if I wanted to access the <userTabLayout id="B"> node, how would I do that?
By traversing the document, e.g. accessing the child nodes via the childNodes field (surprise).
Normally I'd read the documentation on this kind of stuff, but the official documentation on the official PHP page, is really sparse.
That's because the DOM is documented by the W3C already, e.g. here: http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/
As that link is specification it might be a bit technical, so harder to work into, however you can consider it complete (e.g. check for realness if you need to know it). Once understanding that DOM is specified, you can related to any DOM documentation available, for example within MDN, even in Javascript (one of the two default implementations by W3C), it works similar in PHP (esp. for traversal or how Xpath works).
Have fun reading!
Well, you can work without the DomXpath.
$xmlS = '
<userSettings>
<tables>
<table id="supertable">
<userTabLayout id="A">{"id":"colidgoeshereX"}</userTabLayout>
<userTabLayout id="B">{"id":"colidgoeshereY"}</userTabLayout>
</table>
<table id="almost-supertable">
<userTabLayout id="A">{"id":"colidgoeshereC"}</userTabLayout>
<userTabLayout id="B">{"id":"colidgoeshereD"}</userTabLayout>
</table>
</tables>
</userSettings>
';
$xmldoc = new DOMDocument();
$xmldoc->loadXml($xmlS);
$table1 = $xmldoc->getElementsByTagName("tables")->item(0);
$userTabLayoutA = $table1->getElementsByTagName("userTabLayout")->item(0);
$userTabLayoutB = $table1->getElementsByTagName("userTabLayout")->item(1);
echo $userTabLayoutA->nodeValue; // {"id":"colidgoeshereX"}
echo $userTabLayoutB->nodeValue; // {"id":"colidgoeshereY"}
As you can see, you can access all elements, one by one, using getElementsByTagName and specifying what item do you want.

Filtering XML attributes with xpath in PHP

This is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<sets>
<set name="default">
<phpClass name="ArrayIterator" />
</set>
<set name="production" basedOn="default">
<phpVersion>
<min>5.3.0</min>
</phpVersion>
</set>
</sets>
I have to get all items(set) and assign for example phpClass from default (or another) from XML, where sets are connected with basedOn. There is much more main sets (set with diffarent name) and a lot of sets with basedOn. This must be dynamically on more websites, I do not know all names and basedOn-s, so it will be dynamically script.
This is PHP what I have now (for testing):
$this->xml = simplexml_load_file($file);
print_r($this->xml->xpath("//sets/set[contains(name, 'default')]"));
But I get this: Array ( )
Any ideas? Maybe I am not much clear, so ask when you don't understand something.
you are trying to select a set that has a name element that contains 'default' you need to use #name to select the attribute instead:
$this->xml = simplexml_load_file($file);
print_r($this->xml->xpath("//sets/set[contains(#name, 'default')]"));
As a sidenote, there seems to be no need to use contains which is ususally used when you have something like a html class attribute where you have multiple classes, here you can just use set[#name='default'] instead.

SimpleXML and PHP (XPATH)

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

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);

Categories