Jump to content

libxslt function


boen_robot
 Share

Recommended Posts

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

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

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

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

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

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

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

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

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

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...