1

I have a javascript file that looks like this:

if (x > 0 && x < 100) {
    $('#thing').append('<foo id="foo' + x + '">' + stuff + '</foo>');
}

And an xsl stylesheet that looks like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="foo">
        <div>
            <xsl:copy-of select="@*"/>
            <xsl:value-of select="."/>
        </div>
     </xsl:template>
</xsl:stylesheet>

I want to be able to apply that template and possibly other ones to the xml contained in the javascript file.

In this case, the output should look like this:

if (x > 0 && x < 100) {
    $('#thing').append('<div id="foo' + x + '">' + stuff + '</div>');
}

I will use the following constraints on the javascript file if it makes it easier to parse:

  1. I will never use &, <, or > inside or between the XML tags.
  2. I will never use nested XML tags.
  3. I will only use double quotes (") in or around the XML tags to set the element attributes.
  4. I will always have one or more spaces surrounding each < or > character in the regular javascript parts of the text.

I might be able to make other constraints as necessary.

I am using Saxon, so I can use XSLT 2.0 functions and saxon extensions.

4
  • 1
    This would be a new and interesting way of (ab)using XSLT. I'm curious to see what the XSL gurus will come up with. Commented Feb 18, 2012 at 1:53
  • I can't think of any way that XSLT will be of help here; actually I would like to suggest you use javascript (!) to update this javascript code. Remember that XSLT acts on XML, not on text files containing parts of XML scattered all around the place. Commented Feb 18, 2012 at 8:22
  • I ended up writing a script that encodes only the javascript operators (using this regex: / ((<|>|&)+)(=*) /g). It then adds some tags to the header and footer to make it proper xml. Then it transforms that with XSLT and then it un-encodes the result so I end up with regular javascript again. Commented Feb 22, 2012 at 2:14
  • do you depend on xslt 2.0 features? can you call the client-side xslt processor from your js code instead? Commented Feb 28, 2012 at 18:13

1 Answer 1

1

This seems to work (your input text in jsxml.txt):

$ saxon9 -it main jsxml.xsl
if (x > 0 && x < 100) {
    $('#thing').append('<div id="foo' + x + '">' + stuff + '</div>');
}


<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:dpc="data:,dpc">

<xsl:import href="http://web-xslt.googlecode.com/svn/trunk/htmlparse/htmlparse.xsl"/>

<xsl:output method="text"/>

<xsl:template name="main">
 <xsl:variable name="in" select="unparsed-text('jsxml.txt')"/>
  <xsl:copy-of select="dpc:serialise(dpc:apply-templates(dpc:htmlparse($in,'',false())))"/>
 </xsl:template>


<xsl:function name="dpc:apply-templates">
 <xsl:param name="n"/>
 <xsl:apply-templates select="$n"/>
</xsl:function>

<xsl:function name="dpc:serialise">
 <xsl:param name="n"/>
 <xsl:apply-templates select="$n" mode="verb"/>
</xsl:function>

<xsl:template mode="verb" match="*">
 <xsl:value-of select="concat('&lt;',name())"/>
 <xsl:value-of select="@*/concat(' ',name(),'=&quot;',.,'&quot;')"/>
 <xsl:value-of select="'&gt;'"/>
 <xsl:apply-templates mode="verb"/>
 <xsl:value-of select="concat('&lt;/',name(),'&gt;')"/>
</xsl:template>



<xsl:template match="foo">
 <div>
  <xsl:copy-of select="@*"/>
  <xsl:value-of select="."/>
 </div>
</xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

2 Comments

+1 Very cool that you have written your own html parser in xslt 2.0. I'll go ahead and accept this answer.
OK:-) If you are using this for real take a copy of the code and reference that, don't pull it off googlecode repeatedly, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.