InfinityQuest - Programming Code Tutorials and Examples with Python, C++, Java, PHP, C#, JavaScript, Swift and more

Menu
  • Home
  • Sitemap

Python Programming Language Best Tutorials and Code Examples

Learn Python Right Now!
Home
PHP
Calling PHP Functions from XSLT Stylesheets in PHP
PHP

Calling PHP Functions from XSLT Stylesheets in PHP

InfinityCoder December 8, 2016

You want to call PHP functions from within an XSLT stylesheet.

Invoke the XSLTProcessor::registerPHPFunctions() method to enable this functionality:

1
2
$xslt = new XSLTProcessor();
$xslt->registerPHPFunctions();

And use the function() or functionString() function within your stylesheet:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl"
    xsl:extension-element-prefixes="php">
 
<xsl:template match="/">
    <xsl:value-of select="php:function('strftime', '%c')" />
</xsl:template>
 
</xsl:stylesheet>

XSLT parameters are great when you need to communicate from PHP to XSLT. However, they’re not very useful when you require the reverse.

You can’t use parameters to extract information from the stylesheet during the transformation. Ideally, you could
call PHP functions from a stylesheet and pass information back to PHP.
Fortunately, there’s a method that implements this functionality: registerPHPFunctions(). Here’s how it’s enabled:

1
2
$xslt = new XSLTProcessor();
$xslt->registerPHPFunctions();

This allows you to call any PHP function from your stylesheets. It’s not available by default because it presents a security risk if you’re processing stylesheets controlled by other people.
Both built-in and user-defined functions work. Inside your stylesheet, you must define a namespace and call the function() or functionString() methods, as shown:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl"
    xsl:extension-element-prefixes="php">
 
<xsl:template match="/">
    <xsl:value-of select="php:function('strftime', '%c')" />
</xsl:template>
 
</xsl:stylesheet>

At the top of the stylesheet, define the namespace for PHP: http://php.net/xsl. This example sets the namespace prefix to php.

Also, set the extension-elementprefixes value to php so XSLT knows these are functions.
To call a PHP function, reference php:function(). The first parameter is the function name; additional parameters are the function arguments.

In this case, the function name is strftime and the one argument is %c. This causes strftime to return the current date
and time.
This example uses the stylesheet, stored as strftime.xsl, to process a single-element XML document:

1
2
3
4
5
6
7
8
9
10
11
$dom = new DOMDocument;
$dom->loadXML('<blank/>');
$xsl = new DOMDocument;
$xsl->load(__DIR__ . '/strftime.xsl');
 
$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsl);
$xslt->registerPHPFunctions();
print $xslt->transformToXML($dom);
 
Mon Jul 22 06:01:10 2014

This works like standard XSLT processing, but there’s an additional call to registerPHP Functions() to activate PHP function support.
You can also return DOM objects. Example 12-2 takes the XML address book and mangles all the email addresses to turn the hostname portion into three dots.

Everything else in the document is left untouched.
Example 12-2. Spam protecting email addresses

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function mangle_email($nodes) {
    return preg_replace('/([^@\s]+)@([-a-z0-9]+\.)+[a-z]{2,}/is',
                        '$1@...',
                        $nodes[0]->nodeValue);
}
 
$dom  = new DOMDocument;
$dom->load(__DIR__ . '/address-book.xml');
$xsl  = new DOMDocument;
$xsl->load(__DIR__ . '/mangle-email.xsl');
 
$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsl);
$xslt->registerPhpFunctions();
print $xslt->transformToXML($dom);

Inside your stylesheet, create a special template for /address-book/person/email elements.
As an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl"
    xsl:extension-element-prefixes="php">
 
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
 
<xsl:template match="/address-book/person/email">
  <xsl:copy>
    <xsl:value-of select="php:function('mangle_email', node())" />
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

The first template ensures that the elements aren’t modified, and the second passes the current node to PHP for mangling.

In the second template, the mangle_email() function is passed the current node, represented in XPath as node(), instead of a string.

Be sure not to place the node() inside quotation marks, or you’ll pass the literal text node().
Nodes become DOM objects inside PHP and always arrive in an array. In this case, mangle_email() knows there’s always only one object and it’s a DOMText object, so the email address is located in $nodes[0]->nodeValue.
When you know that you’re only interested in the text portion of a node, use the functionString() function.

This function converts nodes to PHP strings, which allows you to omit the array access and nodeValue dereference:

1
2
3
4
5
6
7
function mangle_email($email) {
    return preg_replace('/([^@\s]+)@([-a-z0-9]+\.)+[a-z]{2,}/is',
                        '$1@...',
                        $email);
}
 
// all other code is the same as before

The new stylesheet template for /address-book/person/email is:

1
2
3
4
5
6
<xsl:template match="/address-book/person/email">
<xsl:copy>
  <xsl:value-of
    select="php:functionString('mangle_email', node())" />
</xsl:copy>
</xsl:template>

 

The mangle_email() function now processes $email instead of $nodes[0]- >nodeValue because the template now calls the functionString() function.
The function() and functionString() methods are incredibly useful, but using them undermines the premise of XSL as a language-neutral transformation engine.

When you call PHP from XSLT, you cannot easily reuse your stylesheets in projects that use Java, Perl, and other languages, because they cannot call PHP.

Therefore, you should consider the trade-off between convenience and portability before using this feature.

Share
Tweet
Email
Prev Article
Next Article

Related Articles

Creating a Dynamic Variable Name in PHP
You want to construct a variable’s name dynamically. For example, …

Creating a Dynamic Variable Name in PHP

Ensuring Input Is Filtered in PHP
You want to filter all input prior to use. Initialize …

Ensuring Input Is Filtered in PHP

About The Author

InfinityCoder
InfinityCoder

Leave a Reply

Cancel reply

Recent Tutorials InfinityQuest

  • Adding New Features to bash Using Loadable Built-ins in bash
    Adding New Features to bash Using Loadable …
    June 27, 2017 0
  • Getting to the Bottom of Things in bash
    Getting to the Bottom of Things in …
    June 27, 2017 0

Recent Comments

  • fer on Turning a Dictionary into XML in Python
  • mahesh on Turning a Dictionary into XML in Python

Categories

  • Bash
  • PHP
  • Python
  • Uncategorized

InfinityQuest - Programming Code Tutorials and Examples with Python, C++, Java, PHP, C#, JavaScript, Swift and more

About Us

Start learning your desired programming language with InfinityQuest.com.

On our website you can access any tutorial that you want with video and code examples.

We are very happy and honored that InfinityQuest.com has been listed as a recommended learning website for students.

Popular Tags

binary data python CIDR convert string into datetime python create xml from dict python dictionary into xml python how to create xml with dict in Python how to write binary data in Python IP Address read binary data python tutorial string as date object python string to datetime python

Archives

  • June 2017
  • April 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
Copyright © 2021 InfinityQuest - Programming Code Tutorials and Examples with Python, C++, Java, PHP, C#, JavaScript, Swift and more
Programming Tutorials | Sitemap