开发者

Is there a way to preview multiple XSLT stylesheets that work on the same XML?

I'm building several XSLT stylesheets (e.g. "hotels.xsl", "flights.xsl", "tickets.xsl", etc..) that will all use the same XML document as source (called "schedule.xml" in this case) and output HTML. The final process that uses the XML and XSLTs will take care of itself, but I'm looking for the best way to do previews while working on them. Right now, I keep a copy of the schedule.xml file in the same directory as the working XSLT docs and use a processing instruction to preview a single style sheet in a web browser. For example, using:

<?xml-stylesheet type="text/xsl" href="hotels.xsl"?>

Of course, this means I either have to change the stylesheet reference, or make multiple copies of the XML document that each contain their own stylesheet reference to se开发者_如何学Ce the HTML output in the browser. It's not a huge pain to do either of those things, but I'd like to avoid them if possible to speed things up.

So the question becomes:

Short of writing a little script to help with the process, is there a way to see the HTML output in a browser for each stylesheet without either changing the link in or making multiple copies of the XML?


  1. Use an XML development environment like oXygen to set up multiple "transformation scenarios", each of which is configured to send its output to a browser for preview. You can switch between scenarios by switching between stylesheet buffers.
  2. Use an XML development framework like Cocoon or Calabash (maybe even Servlex) to configure a pipeline for each stylesheet. In Cocoon and Servlex, the different pipelines can be selected by means of separate URLs.

These both take some setup time, but may be worth it, depending on how intense your development / testing is. On the other hand, your multiple-copies-of-the-XML-document idea is pretty easy to set up, and quick to use. As long as the document isn't changing very often.


I ended up writing a PHP file to run in my localhost web server. It's a template with just one variable that needs to be changed to identify the path to the XML file to transform. When it's called, it delivers that XML with the appropriate stylesheet processing instruction inserted.

The things I like about this approach are:

  • Setting up new transformations to test is quick and easy. Just duplicate the php file, rename it and change the path to the XML if necessary.
  • Testing updated XML data is easy. Compared to having multiple copies of the source XML document, this approach uses a single file. When updates are made to it, they are seen in every transformation.
  • Checking changes can be done very quickly with hot keys. A quick Cmd+S, Cmd+Tab, Cmd+R saves the stylesheet in the editor, jumps to the browser and reloads so fast it's barely noticeable.
  • Since the path to the XML document is defined in the code, I can use variables in it whenever needed. For example, passing a unique ID to pull a file with the corresponding value in its name.
  • No other software to install since my machine already has apache with php up and running.

The template code for the php file is:

<?php

// Set the path to the XML file you want to use.
$xmlPath = "example.xml";

////////////////////////////////////////////////////////////////////////////////
// You shouldn't have be mess with any of this.

// Let the browser know XML is on the way. 
header('Content-type:  text/xml');

// get the basename of the current file
$fileBaseName = basename($_SERVER["SCRIPT_NAME"], ".php");

// setup the stylesheet to use
$xsltStylesheet = sprintf('<?xml-stylesheet type="text/xsl" href="%s.xsl"?>', $fileBaseName);

// pull in the contents of the source XML file. 
$xmlData = file_get_contents($xmlPath);

// split the file data looking for processing instructions
$splitArray = explode("?>", $xmlData);

// Pop the main data off the end of the array
$mainData = array_pop($splitArray);

// If there were no headers, push a default onto the split array
if(count($splitArray) == 0) {
    array_push($splitArray, '<?xml version="1.0" encoding="UTF-8"?>');
    array_push($splitArray, $xsltStylesheet);
}

// otherwise check the headers to see if there is already a stylesheet
else {

    // set a flag to watch for a stylesheet
    $hasStylesheet = 0;

    // loop thru the headers
    foreach ($splitArray as &$splitItem) {
        // add the closing string back in.
        $splitItem .= '?>';

        // See if it's a stylesheet call
        if(strrpos($splitItem, '<?xml-stylesheet')) {

            // update the flag to show you hit a stylesheet
            $hasStylesheet = 1;

            // change the href call for the style sheet. 
            $splitItem = preg_replace('/\shref="[^"]*"/', ' href="' . $fileBaseName . '.xsl"', $splitItem);
        }
    }

    // If you didn't find a stylesheet instruction, add it.
    if(!$hasStylesheet) {
        array_push($splitArray, $xsltStylesheet);
    }

}

// reassemble the data
$mainData = implode("\n", $splitArray) . $mainData;

echo $mainData;

To use it,

  1. Create the stylesheet in a directory that is accessible through a web server.
  2. Make a copy of the PHP code in the same directory with the same base filename as the stylesheet. For example, if the stylesheet is "test-example.xsl", the php file would be "test-example.php".
  3. Update the "$xmlPath" variable in the php file to point to the XML to use for testing.
  4. Open the php page through the web browser (e.g. http://localhost/test-example.php) and see the results of the transformation.

In its current state, this code should be decently robust. It will add stylesheet calls to XML files that don't already have them and change stylesheet calls in ones that do. As with anything, it could be built out even more, but it covers what I need it to for now.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜