insertBefore xml php - php

first time over here :o) ... need your help as this is driving me crazy this far away ... Right..
I have this xml structure:
<?xml version="1.0" encoding="UTF-8"?>
<juiceboxgallery galleryTitle="whatever">
<image imageURL="images/23.jpg" thumbURL="thumbs/23.jpg" linkURL="images/23.jpg" linkTarget="_blank" sourcePath="webadded"></image>
<image imageURL="images/24.jpg" thumbURL="thumbs/24.jpg" linkURL="images/24.jpg" linkTarget="_blank" sourcePath="webadded"></image>
... and so on ...
</juiceboxgallery>
And i want to insert new elements just before de first 'image' on the list...
What's the right way to do it..??
All my tries are resulting inserting just before 'juiceboxgallery' or after the closing tag. No way to put it where i want...
Trying to get the the first image element with getElemtnstByTagName("image")->item(0) and doing an insertBefore($new_donde,$first_node) throws me a Not Found Error!! with this code...
$nodo_zero=$doc->getElementsByTagName('image')->item(0);
$doc->insertBefore($nuevo_nodo,$nodo_zero);
.. even when cheking that I have 'X' image elements with this:
$images=$doc->getElementsByTagName("image");
echo "<hr>imagenes: ".$images->length."<hr>";
.. please some help :|

Methods like insertBefore() and appendChild() have to be called on the parent node. The document itself is a node, too. So it has the methods and allows to add multiple nodes, but only a single element node.
In your case, here are to possible approaches.
Use the DOMNode::parentNode property
$nodo_zero = $doc->getElementsByTagName('image')->item(0);
$nodo_zero->parentNode->insertBefore($nuevo_nodo,$nodo_zero);
Or fetch the juiceboxgallery node and use the DOMNode::firstChild property.
$gallery = $doc->getElementsByTagName('juiceboxgallery')->item(0);
$gallery->insertBefore($nuevo_nodo, $gallery->firstChild);

Related

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.

simplexml add child non attribute information

i'm trying to figure out how to add this right here;
<tech name="level 0" prereq="0" id="7" null="null">
<meta fuelx="1" energyx="1" cost="100" income="11">Description goes here</meta>
</tech>
to an already existing xml file.
I've gotten the first and the but I cannot figure out how to add the information between the &.
You can't add child nodes w/ SimpleXML. You can convert to DOM and then do it though.
$curNode = dom_import_simplexml($simpleXml);
$newChild = dom_import_simplexml($sXml);
$tmpNode = $curNode->ownerDocument->importNode($newChild, true);
$curNode->appendChild($tmpNode);
EDIT
Wow, it seems like they added an addChild method in 5.1.3, where have I been??

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

PHP XML DOM getElementById

I need to pick one tag from xml file and insert another tag before this tag. I'm doing this with method insertBefore in DOM, but the problem is, that if I want pick the tag before I want to add the another tag by method getElementById, it doesn't work.
It writes "using non-object". This is how the tag looks:
<item id="Flow_0" href="Flow_0.html" media-type="application/xhtml+xml"/>
Somewhere I read that it must look like this, but I can't edit all files:
<item xml:id="Flow_0" href="Flow_0.html" media-type="application/xhtml+xml"/>
Have you got any idea how to do that?
A common workaround is to use XPath to get the element.
$item = $xpath->query('//item[#id="Flow_0"]')->item(0);

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

Categories