Page 1 of 1

XML and PHP

Posted: Thu Feb 17, 2011 10:30 am
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?

Re: XML and PHP

Posted: Thu Feb 17, 2011 10:43 am
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>

Re: XML and PHP

Posted: Thu Feb 17, 2011 10:48 am
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);

Re: XML and PHP

Posted: Thu Feb 17, 2011 1:08 pm
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

Re: XML and PHP

Posted: Thu Feb 17, 2011 1:17 pm
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.

Re: XML and PHP

Posted: Thu Feb 17, 2011 5:37 pm
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";

Re: XML and PHP

Posted: Fri Feb 18, 2011 7:56 am
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?

Re: XML and PHP

Posted: Fri Feb 18, 2011 8:56 am
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).