boen_robot Posted October 8, 2006 Share Posted October 8, 2006 I use PHP5's XSLT processor (libxslt) very often, so I decided to build a function for it.Here's what I have until now: <?php//Define a function and it's arguments.function xsltProcessor($xmlFile,$xsltFile,$parameters,$options){ //Prepare the XML file. $xml = new DomDocument; $xml->load($xmlFile); //Prepare the XSLT file. $xsl = new DomDocument; $xsl->load($xsltFile); //Load the XSLT processor. $processor = new Xsltprocessor; $processor->importStylesheet($xsl); //Assign the paramets' values to the proper parameters. function xsltProcessorParameters($value,$key) { return $processor->setParameter(NULL, $key, $value); } array_walk($parameters,"xsltProcessorParameters"); //Execute the transformation. $transformation = $processor->transformToXml($xml); //Check the output. if ($options) { foreach ($options as $option) { if ($option = "removeEmptyXMLNS") { //Remove the empty xmlns attributes that sometimes get created. $output = ereg_replace(' xmlns=""','',$transformation); } } //Return the transformation with options. $result = $output; }else { //Return the transformation without options. $result = $transformation; }return $result;}echo xsltProcessor("test.xml","test.xsl",NULL,NULL);?> It works with any XML and XSLT file, but it has one major problem. Very often I need to pass parameters to the stylesheet before the transformation. I have the third argument set up for that, but it's not working. It's supposed to be an associative array who's keys represent the parameter names and who's values represent the parameter's value. What I have attempted for it are the lines: //Assign the paramets' values to the proper parameters. function xsltProcessorParameters($value,$key) { return $processor->setParameter(NULL, $key, $value); } array_walk($parameters,"xsltProcessorParameters"); Which I created thanks to the W3Schools PHP reference. When the function is called without the third argument, it works, but with this argument, not only the parameter is not passed, but the complete output is a blank screen. As if there's a critical error in PHP script itself. Example of a call that fails: echo xsltProcessor("test.xml","test.xsl",array("parameter1"=>"value1"),NULL); I tryed removing the "return" but that doesn't work either. Link to comment Share on other sites More sharing options...
boen_robot Posted October 11, 2006 Author Share Posted October 11, 2006 OK. Let me generalize the question. How can I loop through the key names and values of an associative array and perform a certain PHP action based on each key name and value? The loop must not alone return something (the way a function does) but must rather repeat the same action in the procedure (or function) in which it's used. Link to comment Share on other sites More sharing options...
jesh Posted October 11, 2006 Share Posted October 11, 2006 Does this link help? http://us2.php.net/foreach Link to comment Share on other sites More sharing options...
boen_robot Posted October 11, 2006 Author Share Posted October 11, 2006 Does this link help? http://us2.php.net/foreach using foreach was the first thing on my mind, but I never knew it could also assign the key name of the array to a variable. Thanks a million. Link to comment Share on other sites More sharing options...
boen_robot Posted October 11, 2006 Author Share Posted October 11, 2006 One more thing. I currently use: if ($options) { foreach ($options as $option) { if ($option = "removeEmptyXMLNS") { $output = ereg_replace(' xmlns=""','',$transformation); //Remove the empty xmlns attributes that sometimes get created. } } //Return the transformation with options. return $output; } And it works, but it somehow seems as low performance and unstable. Is there a way to check each $option without repeating the same "if" on true? I mean, the current form allows me to add: if ($option = "removeEmptyXMLNS") { $output = ereg_replace(' xmlns=""','',$transformation); //Remove the empty xmlns attributes that sometimes get created. }elseif ($option = "whatever") { //Some action } But if there are two $option = "whatever" the option will needlessly be performed two times and scince it was already applied once, it's needless to check other $option variables for the same thing. Link to comment Share on other sites More sharing options...
jesh Posted October 11, 2006 Share Posted October 11, 2006 I don't fully understand how the PHP engine handles conditionals. In C#, however, I understand that the compiler optimizes some code and using a switch can be MUCH faster than a series of if ... else if ... elses.Maybe something like this would increase performance: switch($option){ case "removeEmptyXMLNS": // code to handle this case. break; case "someothervalue": // code to handle "someothervalue". break; default: // code to handle all other cases. break;} Link to comment Share on other sites More sharing options...
boen_robot Posted October 11, 2006 Author Share Posted October 11, 2006 right... switch.... I read that once upon a time and I forgot about it's existence! Damn, I ask the most noobish questions around . Shame on me. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 11, 2006 Share Posted October 11, 2006 About this code: if ($option = "removeEmptyXMLNS"){ $output = ereg_replace(' xmlns=""','',$transformation);} That IF statement will always evaluate to true, because you used = instead of ==. So it is assigning the value of "removeEmptyXMLNS" to the variable $option, and then testing $option for boolean true, and since it is a non-empty string it will evaluate to true and always execute the ereg_replace function. So, that's probably the source of your slowdown. But, you can also do something like this: $remove = true; foreach ($options as $option) { if ($remove && $option == "removeEmptyXMLNS") { $output = ereg_replace(' xmlns=""','',$transformation); $remove = false; } } That way, the replace will only be performed once. Link to comment Share on other sites More sharing options...
boen_robot Posted October 11, 2006 Author Share Posted October 11, 2006 I think for this specific case, the switch might be more appropriate, though I appreciate the alternative approach.But thanks for the "=" and "==" tip. I didn't realized there's a difference. Wow, 10 minutes and I already know more about PHP then ever before (and yes, I know that's just the start) . Link to comment Share on other sites More sharing options...
justsomeguy Posted October 11, 2006 Share Posted October 11, 2006 There is also a === operator, which checks for type equivalence as well as value. So, this would evaluate to true:0 == "0"But this is false:0 === "0"It's useful for distinguishing between 0 and false. A function like strpos returns the position of a character in a string, and false if it's not found. So, to distinguish between strpos finding a character in position 0 and not finding it at all, you useif (strpos(...) === false) Link to comment Share on other sites More sharing options...
boen_robot Posted October 11, 2006 Author Share Posted October 11, 2006 Wow. You're certanly on fire today .I feel bad that I don't have other things to throw at you right now while I have the chance .Wait, I just remembered I do .Simple XML xpath() function returns a multidimensional array. What I wonder is how to access multidimensional arrays. For example: Array ( [0] => SimpleXMLElement Object ( [0] => A result of the query ) ) How to access deeper levels of this array? And is there a way to detect if there is another dimension in the array and progress on it if so, instead of always processing a selected dimension as a whole. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 11, 2006 Share Posted October 11, 2006 Indeed there is!First, if you have a multidimensional array, say with 3 dimensions, then you can access it like this:$var[$i][$j][$k]Or, you can even grab one dimension as a whole and loop through it:for ($i = 0; $i < count($var[1][2]); $i++)would iterate through the third array. It would take 3 loops to go through the entire structure: for ($i = 0; $i < count($var); $i++) for ($j = 0; $j < count($var[$i]); $j++) for ($k = 0; $k < count($var[$i][$j]); $k++) $var[$i][$j][$k] = ...; If you want to check if a variable is an array, you can use is_array. if (is_array($var[$i])){ for ($j = 0; $j < count($var[$i]); $j++) ...}else{ ...} Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now