tags:

views:

108

answers:

3

Hello everyone,

I'm trying to use XSLT to create Edge Side Includes html blocks.

Here is a sample XSLT

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:esi="http://www.edge-delivery.org/esi/1.0" 
                exclude-result-prefixes="xsl esi">

    <xsl:output method="html" 
                media-type="text/html" 
                version="1.0" 
                encoding="UTF-8" 
                indent="no" 
                omit-xml-declaration="yes"/>

    <xsl:template match="/">
        <esi:vars>
            <xsl:text>some text goes here</xsl:text>
        </esi:vars>
    </xsl:template>

</xsl:stylesheet>

While the transformation works per-se, the output is this:

<esi:vars xmlns:esi="http://www.edge-delivery.org/esi/1.0"&gt;some text goes here</esi:vars>

problem is, the xmlns:esi attribute horribly breaks ESI execution. If I remove the attribute manually (eg: open the HTML and delete it, saving the code block again) everything works fine.

Question: How can I remove the xmlns:esi from the HTML output? I tried including it in exclude-results-prefixes, but didn't work.

Sample output that WILL work:

<esi:vars>some text goes here</esi:vars>
+2  A: 

Question: How can I remove the xmlns:esi from the HTML output? I tried including it in exclude-results-prefixes, but didn't work.

XSLT with output method xml cannot produce non-well-formed XML.

When the namespace declaration is deleted manually, the "esi:" prefix becomes not bound to any namespace and thie whole document thus becomes non-well-formed.

According to the ESI Spec., the esi namespace must typically be declared in the top element (<html>) of the document.

Try this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:esi="http://www.edge-delivery.org/esi/1.0"&gt;
<xsl:output indent="no" omit-xml-declaration="yes"/>

<xsl:template match="/">
   <html xmlns:esi="http://www.edge-delivery.org/esi/1.0"&gt;
    <esi:vars>
        <xsl:text>some text goes here</xsl:text>
    </esi:vars>
    </html>
</xsl:template>

</xsl:stylesheet>

which produces:

<html xmlns:esi="http://www.edge-delivery.org/esi/1.0"&gt;
    <esi:vars>some text goes here</esi:vars>
</html>
Dimitre Novatchev
Thank you Dimitre, but my output method is html, <xsl:output method="html">. Guess that doesn't work anyway.Problem is, my html code fragment is to be included via esi:include, so i JUST need to produce the fragment without the wrapping <html> tag.
sh0uzama
@sh0uzama: Then you are out of luck... In case you don't use esi:include this will work. You can try to do the include using XSLT.
Dimitre Novatchev
@Dimitre: :( bad news then - I'll see if I can find a workaround. Writing it in xsl:text blocks will do the job (as stated below), but doesn't quite suits my needs (readability, mainly). Oh well.
sh0uzama
@sh0uzama: You can also use DOE (disable-output-escaping="yes"), but this is even uglier and is not supported by all XSLT processors.
Dimitre Novatchev
this line <xsl:output indent="no" omit-xml-declaration="yes"/> only works for XSL document. When it comes to .net, setting is passed exactly as stated in XSL document, but the XslCompiledTransform doesn't care. It ignores my changes...
Eduardo Xavier
@Eduardo-Xavier: In .NET you need to take these decisions in the XmlWriter that you pass as argument to the transformation.
Dimitre Novatchev
@Dimitre Novatchev: .NET classes left me on dire straits. Your wrapper solutions works nice for me. I did remove the wrapper tag using RegEx.
Eduardo Xavier
@Eduardo-Xavier: Glad it worked well! If you are happy, you could even consider accepting my answer :)
Dimitre Novatchev
Admitting a post-processing, yes, this is the best solution. It allows you to write esi code directly without DOE.
sh0uzama
+2  A: 

With any input, this stylesheet:

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

<xsl:template match="/">
    <xsl:text>&lt;esi:vars></xsl:text>
        <xsl:text>some text goes here</xsl:text>
    <xsl:text>&lt;/esi:vars></xsl:text>
</xsl:template>

</xsl:stylesheet>

Result:

<esi:vars>some text goes here</esi:vars>

Note: For no-well-formed output you can use DOE or TEXT serialization only.

Alejandro
Thank you Alejandro. That was basically what I did before. It works without hassles, it's just very ugly to read.I was trying to find out a way to write down ESI code keeping readability.
sh0uzama
@sh0uzama: You are wellcome! The problem here isn't to write down ESI code. The problem is that your output is a fragment (not the complete document) and this fragment without namespace declaration is not wellformed.
Alejandro
I've spent the whole day trying figure out this shit. Apart from many oak samples in the internet, that shit doesn't work at all. We need somehow put < at HTML tags so that it can works.I'm sorry too... terrible I mean!
Eduardo Xavier
@Eduardo Xavier: Yes, this is problematic. But all the blame lies with ESI because it request a prefix but does not handles namespaces well. All ESI's user should sumit a fix request.
Alejandro
@Alejandro: Dimitre Novatcheve's solution is the best one. It worked for me. I manually removed the wrapper tag using C# and regex.
Eduardo Xavier
@Eduardo Xavier: Yes, I also think that wrapping ESI elements with other (any) element that declare the namespace is better. But that does not cover every scenario. So, you endded up with two codes in two language for the same task. I think that the very best solution is doing the include directly with XSLT (this add the parser time in XLST 1.0 but don't in XSLT 2.0)
Alejandro
@Alejandro: you are right. Best thing is, I think Dimitre's solution can fit to most scenarios (so I guess I had to give him the "Answer"), but for my specific case... I used your solution (well, actually we already used <![CDATA[]]> blocks to write ESI)
sh0uzama
@sh0uzama: You can choose the answer that you want. I don't dispute that right. But, I think your questions is about output malformed XML, and this can be done only with DOE or text serialization.
Alejandro
Yes, you are completely right... I can't give "Accepted Answer" to you both, but I wish I could... :(
sh0uzama
@Alejandro @sh0uzama I've found a better way to do it. It worked for me.
Eduardo Xavier
+1  A: 

I've found the professional way to do it. The right answer depends on the following:

<xsl:stylesheet
  version="1.0" xmlns:asp="remove"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:app="http://myNamespace.com/app" 
  exclude-result-prefixes="app">

use this function here exclude prefixes

exclude-result-prefixes

For more information: http://msdn.microsoft.com/en-us/library/ms256204.aspx

Eduardo Xavier
@Eduardo Xavier: First, your professional solution don't answer the question **How can I remove the xmlns:esi from the HTML output?** . This means: how can I have a namespace prefix without a namespace declaration. The answer, the only answer, is that if want a non well-formed tree you need DOE or text serialization. Second, `xsl:stylesheet/@exclude-result-prefixes` is a standar XSL attribute, so you should quot the specs (no MS documentation): http://www.w3.org/TR/xslt#literal-result-element . And last, with your answer, another process is needed: removing the namespace declaration...
Alejandro
@Alejandro I used MS doc 'cause is what I use to perform transformation. Anyway.. it worked for me. I'll do more experiments and see...
Eduardo Xavier