2

Edit - Solution:

I took some inspiration from @Tomalak solution. However, instead of using XSLT I used the VS Code replace regex expressions to comment out my XML code:

<!-- comment out xml tags : ^(\s*(\]\]>)?<\/?\w*>(<!\[CDATA\[)?)\s*$ --> 
<!-- comment out xml tags : //$1 --> 
<!-- uncomment xml tags   : ^\/\/(\s*(\]\]>)?<\/?\w*>(<!\[CDATA\[)?)\s*$ --> 
<!-- uncomment xml tags   : $1 --> 

Using $1 will give you the capture group. I'm just capturing all XML tags and adding the // characters to make them a comment.

From there I just set the syntax highlighting of the file to JavaScript and everything worked flawlessly.

I only need to do this once in a while, so this quick hack will work fine for me. However a more sophisticated solution such as an XSLT template might be better for more active projects.

Problem

I have an XML file containing javascript (Due to constraints of the platform we are using.) My code looks like this:

<JS>
  <MY_FUNCTION><![CDATA[
// comment here
let my_function = () => console.log("Hello World");
  ]]></MY_FUNCTION>
  <LESS_THAN><![CDATA[
let less_than = (a,b) => a < b;
  ]]></LESS_THAN>
  <GREATER_THAN><![CDATA[
let greater_than = (a,b) => a > b;
  ]]></GREATER_THAN>
</JS>

Being that my file is XML I'm not getting syntax highlighting for the javascript. So my code is just grey, similar to how comments look.

Is there an extension that could highlight my code? I'd also be willing to modify the highlighting rules if that would help me.

3
  • 3
    I very much doubt there's a plugin that takes care of this usecase... Mixing languages like that is often uncharted territory. Commented Apr 14, 2021 at 14:06
  • This seems relevant: github.com/Microsoft/vscode/issues/1751 Commented Apr 14, 2021 at 14:44
  • At the risk of stating the obvious: a workaround for this, if your platform supports it, is to do a file include to include the JS file, or use templating to inject a js files contents into the XML. Commented Apr 14, 2021 at 14:47

1 Answer 1

1

You could turn the problem around. This XSLT template transforms your XML to JS code

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" />

    <xsl:template match="*[normalize-space(text()[1])]">
        <xsl:value-of select="concat('//xml:&lt;', name(), '&gt;&lt;![CDATA[')" />
        <xsl:apply-templates select="node() | *" />
        <xsl:value-of select="concat('//xml:]]&gt;&lt;/', name(), '&gt;')" />
    </xsl:template>
    
    <xsl:template match="*">
        <xsl:value-of select="concat('//xml:&lt;', name(), '&gt;')" />
        <xsl:apply-templates select="node() | *" />
        <xsl:value-of select="concat('//xml:&lt;/', name(), '&gt;')" />
    </xsl:template>
</xsl:stylesheet>

produces this:

//xml:<JS>
  //xml:<MY_FUNCTION><![CDATA[
// comment here
let my_function = () => console.log("Hello World");
  //xml:]]></MY_FUNCTION>
  //xml:<LESS_THAN><![CDATA[
let less_than = (a,b) => a < b;
  //xml:]]></LESS_THAN>
  //xml:<GREATER_THAN><![CDATA[
let greater_than = (a,b) => a > b;
  //xml:]]></GREATER_THAN>
//xml:</JS>

Now syntax highlighting can work according to JS rules.

Using XSLT is not strictly necessary, you could probably get away with a half-way clever regex replace, something like ^(\s*)(<|\]\]>) replaced with \1//xml:\2, assuming that XML tags always are on their own lines.

You can convert it all back to XML by removing the //xml: with a simple search and replace operation, as long as you leave the //xml: comments intact.

Doing that would put us back to:

<JS>
  <MY_FUNCTION><![CDATA[
// comment here
let my_function = () => console.log("Hello World");
  ]]></MY_FUNCTION>
  <LESS_THAN><![CDATA[
let less_than = (a,b) => a < b;
  ]]></LESS_THAN>
  <GREATER_THAN><![CDATA[
let greater_than = (a,b) => a > b;
  ]]></GREATER_THAN>
</JS>
Sign up to request clarification or add additional context in comments.

2 Comments

Great solution! I took some inspiration from your answer and used the VS Code regular expression tool to do essentially the same thing (comment out / uncomment XML tags)
@CodyMaxie You could also automate this as part of your build pipeline, if there is such a thing for this.

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.