Transform XML with multiple XSL files

后端 未结 3 2154
一生所求
一生所求 2021-02-19 02:00

I have some XML that I\'d like to transform into HTML using a number of XSL files. These XSL files are all related through xsl:import and xsl:include statements, and all require

相关标签:
3条回答
  • 2021-02-19 02:46

    If you want a Browser only solution I would do it like this:

    Static xml

    Make a simple static xml that contains only the call to the xsl. This is the xml that is opened in the browser - always. This xml file could contain property settings to control the flow or nothing at all as this example.

    <?xml version="1.0" encoding="utf-8"?>
    <?xml-stylesheet type="text/xsl" href="cartoon2html.xsl"?>
    <xml/>
    

    Dynamic plain xml

    Generate the dynamic XML in your favourite way using a defined name - in my case cartoons.xml.

    <?xml version="1.0" encoding="utf-8"?>
    <cartoons>
        <cartoon name="Donald Duck" publisher="Walt Disney" />
        <cartoon name="Mickey Mouse" publisher="Walt Disney" />
        <cartoon name="Batman" publisher="DC Comics" />
        <cartoon name="Superman" publisher="DC Comics" />
        <cartoon name="Iron Man" publisher="Marvel Comics" />
        <cartoon name="Spider-Man" publisher="Marvel Comics" />
    </cartoons>
    

    XSLT with document load

    Use document loan in the xslt to reference the generated dynamic xml. By using select in the first apply-templates all other templates will work as intended.

    Take a close look at the variable reference at top and the further down in the code. This is where the magic is performed.

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:variable name="cartoons" select="document('cartoons.xml')/cartoons" />
    
        <xsl:template match="/">
            <html>
                <head>
                    <title>Cartoons</title>
                    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
                </head>
                <body>
                    <xsl:apply-templates select="$cartoons" />
                </body>
            </html>
        </xsl:template>
    
        <xsl:template match="cartoons">
            <table>
                <xsl:apply-templates />
            </table>
        </xsl:template>
    
        <xsl:template match="cartoon">
            <tr>
                <td><xsl:value-of select="@name" /></td>
                <td><xsl:value-of select="@publisher" /></td>
            </tr>
        </xsl:template>
    
    </xsl:stylesheet>
    

    You could save these three files into a directory of choice and open the static xml file in firefox. (Chrome and perhaps Safari has to have the file served through a web server to perform the transformation).

    0 讨论(0)
  • 2021-02-19 02:46

    I would recommend using jquery to import and style the XML.

    Something like this would allow you to import the XML whenever a function is called (a function linked to a keypress or a refresh button or even a timer.)

    $.ajax({
        type: "GET",
        url: "FILENAME.xml",
        dataType: "xml",
        success: function(xml) {
            $(xml).find('site').each(function(){ //finds parent node
                var id = $(this).attr('id'); //id of parent node
                var title= $(this).find('title').text();  //finds title node within parent node
                var url = $(this).find('url').text(); //finds URL node within parent node
                var description = $(this).find('descr').text(); //etc...
                var img = $(this).find('img').text(); //etc...
    
                // Creates div with id of parent node (for individual styling)
                $('<div id="link_'+id+'">')
                    .addClass('add a div class')
                //sets css of div
                    .css({set css})
                // Sets the inner HTML of this XML allocated div to hyperlinked 'title' with 'description' and an 'img'
                    .html('<a href="'+url+'">'+title+'</a>'+description+'<img src="'+img+'">')                  
                // Append the newly created element to body
                    .appendTo('#holder');
        }
        }
    })
    

    And the XML would look something like this:

    <site id="0">
     <url>http://blah.com</url>
     <img>imgs/image1.png</img>
     <description>this is a description</description>
     <title>Title</title>
    </site>
    
    <site id="1">
     <url>http://filler.com</url>
     <img>imgs/image2.jpg</img>
     <description>this is another description</description>
     <title>Title 2</title>
    </site>
    

    Of course instead of importing to a div you could import the XML to a table or any other type of HTML element.

    0 讨论(0)
  • 2021-02-19 02:48

    I had the same problem just now. My solution was to propagate the includes directly into the XML. This code was tested under Chrome, Firefox and IE 10,9,8 and 7.

    function propegateIncludes(dname,xml, isExplorer) {
        var preTag = isExplorer ? "xsl:" : "";
    
        var TAG_STYLESHEET = preTag + "stylesheet", TAG_INCLUDE = preTag
            + "include", TAG_TEMPLATE = preTag + "template";
    
        var stylesheets = xml.getElementsByTagName(TAG_STYLESHEET);
        if (stylesheets.length == 0) {
            return;
        }
    
        var includes = xml.getElementsByTagName(TAG_INCLUDE);
        if (includes.length == 0) {
            return;
        }
    
        var stylesheet = stylesheets[0];
        var path = dname.substring(0, dname.lastIndexOf('/'));
    
        for ( var i = 0; i < includes.length; i++) {
            var args = includes[i].attributes;
            var includeXml = null;
    
            for ( var a = 0; a < args.length; a++) {
                if (args[a].nodeName == "href") {
                    includeXml = loadXMLDoc(path + "/" + args[a].nodeValue);
                    break;
                }
            }
    
            stylesheet.removeChild(includes[i]);
    
            if (includeXml != null) {
                var templates = includeXml.getElementsByTagName(TAG_TEMPLATE);
    
                for (var t = 0; t < templates.length; ++t) {
                    stylesheet.appendChild(templates[t].cloneNode(true));
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题