XML and PHP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
rampant
Forum Newbie
Posts: 9
Joined: Thu Oct 08, 2009 2:28 pm

XML and PHP

Post by rampant »

So, I have been going through the simpleXML and the DomDocument stuff and while I think I mostly get each part by itself, combining it all has me stumped.

Here is what I am trying to do:

I have a menu tree in xhtml. I want to pull it into a dom document, find a certain list item, and then add a class to all <ul> parents of that list item, then spit back XHTML.

I have created an xpath query which I believe should FIND the right elements to modify (the ul parents) but I have no idea how to now use that selection as a way of altering things

so: xpath://li[@class='current-menu-item']/ancestor::ul

now that I have selected those... how can I apply new attributes to the selected <ul>s? Or am I just going at this all wrong?
rampant
Forum Newbie
Posts: 9
Joined: Thu Oct 08, 2009 2:28 pm

Re: XML and PHP

Post by rampant »

what I have tried:

Code: Select all

<?php
$xmlstring= "(a string that is an xml document that I created and is pretty big so I won't post it here)";

$domDocument=new DomDocument('1.0');


$domDocument->loadHTML($xmlstring); 

$xpath=new DOMXPath($domDocument);

$xpQuery="//li[@class='current-menu-item']/ancestor::ul"; //gets all the ul ancestors of the selected li.current-menu-item

$results= $xpath->query($xpQuery);

//now we need to get the existing class attribute information and append 'active-parent' to it

foreach ($results as $result) {
	$classes=$result->getAttribute('class');
	$classes.=' active-parent';
	$result->setAttribute($classes);
}
?>
<pre>
<?php echo $domDocument->saveHTML();?>
</pre>
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: XML and PHP

Post by Weirdan »

seems ok to me. What exactly does not work, what results you get?

Edit: you need to specify the attribute name though:

Code: Select all

            $result->setAttribute('class', $classes);
rampant
Forum Newbie
Posts: 9
Joined: Thu Oct 08, 2009 2:28 pm

Re: XML and PHP

Post by rampant »

yeah, I saw that bug too as I tried running stuff.

Well, the reason it seemed like it wasn't working at all was because it was returning NO values.

I was like.. WTF?

There should be exactly ONE element with current-menu-item as its class. However, it also has OTHER classes, because this is XHTML.


Well.... in XML an element can only have one value for an attribute (class is an attribute) whereas XHTML you can have a BUNCH of classes. So this thing is like <li class="current-page red exploded-squirrel current-menu-item parent-of-bob" id="squiggles"> stuff </li> OK, I made a bunch of those class names up but you get the idea.

I need to be finding the node for which ANY ONE of the values contains current-menu-item
rampant
Forum Newbie
Posts: 9
Joined: Thu Oct 08, 2009 2:28 pm

Re: XML and PHP

Post by rampant »

AH HAH!

Code: Select all

$xpath="//li[contains(@class,'current-menu-item')]/ancestor::ul"
I hope this helps those who come after me. I can only assume this is a common need.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: XML and PHP

Post by Weirdan »

rampant wrote:AH HAH!

Code: Select all

$xpath="//li[contains(@class,'current-menu-item')]/ancestor::ul"
I hope this helps those who come after me. I can only assume this is a common need.
That would also find elements with classes like 'no-current-menu-item-no-really'
Proper xpath 1.0 for such cases would be

Code: Select all

$xpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' current-menu-item ')]/ancestor::ul";
rampant
Forum Newbie
Posts: 9
Joined: Thu Oct 08, 2009 2:28 pm

Re: XML and PHP

Post by rampant »

ah, good point!

didn't have to worry about that with my particulary application but robust is good.

Couldn't you just use contains(@class, ' current-menu-item ') with the spaces on the ends?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: XML and PHP

Post by Weirdan »

rampant wrote:Couldn't you just use contains(@class, ' current-menu-item ') with the spaces on the ends?
unfortunately not, because that wouldn't match class="current-menu-item another-class" (no space at the beginning).
Post Reply