I am facing a weird issue with an XSLT that should:
* read all subitems of the current page; subitems can be of type A, type B and type C
* each type is rendered in a different way.
In order to accomplish this, I have set up a transformation that selects the nodes of a certain kind and applies a template according to the node type. Here is my first XSLT:
and here is the other bit, which is included at the very beginning of the previous one.
<xsl:template match="TypeA"> <div>pluto</div>
</xsl:template>
For some reason, the nodes of type TypeA are rendered correctly but wrapped around an additional DIV! (which should not exist at all as it is not defined anywhere!).
Not just that! This code is also moving around the DIVs that are built in other XSLTs or controls. For example my normal structure (the one that is correctly output if I take out this XSLT) is:
I have encountered something similar before with weird hierarchy breaks in divs etc. I think what basically happens is that some (or more) closing tags don't get rendered, aka what should be
<div>one</div>
<div>two</div>
<div>three</div>
becomes
<div>one</div>
<div>two
<div>three</div>
[div's automatically closed at the end by browser].
This happens pretty much when you leave one div empty in the xslt, e.g.
<div>
<xsl:value-of select="string('')" />
</div>
will make your page move around. If you set output method of the XSLT to Html it should work fine, however ideally you would leave it at Xml and just be careful with empty values.
If somebody knows an explanation for this behaviour that would be much appreciated (for peace of mind and such ;).
It's really hard to help you without any of the problematic code, but here goes:
I can think of two reasons - the first being related to the output method (as Sascha & Nik are explaining): In XML there is no difference between a self-closing element and an element with zero or a thousand whitespace characters (space, tab, carriage-return etc.) - so when the output method is set to "xml", the processor is free to output <div /> in stead of <div></div> (or any version of that with additional whitespace). If you're not able to test for actual content, you can put an empty comment inside, which will prevent the self-closing version to be rendered, i.e.:
The problem with switching to output method "html" is that you will get <img> instead of <img />, <br> instead of <br /> etc., which is not valid XML (and thus, not valid XHTML).
The other reason could be that any of your TypeA, TypeB or TypeC templates are being applied from within each other, which is a problem when you start by collecting all of them and applying templates to that result set (would return in duplicate renderings, possibly nested inside each other...)
When you refer to a "phantom" div (that should not exist and isn't defined anywhere) I'm guessing your actual problem i #1.
Anyways, show some of the actual code, and we can help you so much easier,
Hi Gianluca, quick question about the extra <div>s ... where are you viewing these? Which browser are you using?
Are you viewing the "source" or the "rendered source"? Rendered source meaning via Firebug, or Chrome's Developer Tools? - if the HTML is invalid, these browsers will "fill in the gaps" and add tags to try to make it valid again. Just some food for though.
Reading your post I assume there must be some wrong formatted html code inside your template. As Lee mentions, which html are you looking at. Take a look at the real source code and try to find a possible error. You can post html source code to w3c validators to check if every tag is closed properly.
I really wish I could mark all of your answers as the correct ones, because they actually are!
Sascha, you were right. The problem were the empty DIVs. The code I wrote was meant to render some "boxes" that are located in a sidebar. Each box can have a title and/or a body. However, it is not mandatory to fill in the two fields. Hence when they were not populated, the xslt was generating an empty <div />, which was causing the issue. I simply verified that at least one of the two fields exists and is not empty, and that solved the problem.
And of course, Lee, you were right too. I am using Chrome, which has an integrated firebug-like tool. I like to look at the html/xml code in there, because it is more readable. However, as you pointed out, it "fills in the gaps"... whenever something is wrong, it tries to fix it by adding a tag that he believes to be the right one. I also tried to view the generated html code in firefox, and guess what? I was using firebug, which behaves in the exact same way. My fault: I didnt know that. And yes, actually looking at the "raw" source code (view source), it was kind of right; at least the divs were in the right position.
Nik, Chriztian, Folkert: thank you for your contribute as well!
No worries about viewing the HTML in the Chrome Dev Tools/Firebug - I use them all the time, AND keep getting caught-out by the "rendered source" too! :-)
DIVs moved around by XSLT
Hello everybody!
I am facing a weird issue with an XSLT that should:
* read all subitems of the current page; subitems can be of type A, type B and type C
* each type is rendered in a different way.
In order to accomplish this, I have set up a transformation that selects the nodes of a certain kind and applies a template according to the node type. Here is my first XSLT:
<xsl:template match="/">
<xsl:apply-templates select="($currentPage/TypeA | $currentPage/TypeB | $currentPage/TypeC)">
<xsl:with-param name="currentPage" select="$currentPage" />
</xsl:apply-templates>
</xsl:template>
and here is the other bit, which is included at the very beginning of the previous one.
<xsl:template match="TypeA">
<div>pluto</div>
</xsl:template>
For some reason, the nodes of type TypeA are rendered correctly but wrapped around an additional DIV! (which should not exist at all as it is not defined anywhere!).
Not just that! This code is also moving around the DIVs that are built in other XSLTs or controls. For example my normal structure (the one that is correctly output if I take out this XSLT) is:
Well, with the XSLT on, the "footer" is moved inside "container"!!!
Is there any reason why this is happening?!?
Thanks in advance,
Cheers,
G.
Hi Gianluca,
I have encountered something similar before with weird hierarchy breaks in divs etc. I think what basically happens is that some (or more) closing tags don't get rendered, aka what should be
<div>one</div>
<div>two</div>
<div>three</div>
becomes
<div>one</div>
<div>two
<div>three</div>
[div's automatically closed at the end by browser].
This happens pretty much when you leave one div empty in the xslt, e.g.
<div>
<xsl:value-of select="string('')" />
</div>
will make your page move around. If you set output method of the XSLT to Html it should work fine, however ideally you would leave it at Xml and just be careful with empty values.
If somebody knows an explanation for this behaviour that would be much appreciated (for peace of mind and such ;).
Hope that helps,
Sascha
This does happen when you try to render empty HTML tags (div or other) if you have the output method set to xml as opposed to html. Like so:
vs.
One fix is to change it to html (which has other implications, like doc type etc.) and the other is to do what Sasha suggests above.
HTH,
Nik
Hi Gianluca,
It's really hard to help you without any of the problematic code, but here goes:
I can think of two reasons - the first being related to the output method (as Sascha & Nik are explaining): In XML there is no difference between a self-closing element and an element with zero or a thousand whitespace characters (space, tab, carriage-return etc.) - so when the output method is set to "xml", the processor is free to output <div /> in stead of <div></div> (or any version of that with additional whitespace). If you're not able to test for actual content, you can put an empty comment inside, which will prevent the self-closing version to be rendered, i.e.:
The problem with switching to output method "html" is that you will get <img> instead of <img />, <br> instead of <br /> etc., which is not valid XML (and thus, not valid XHTML).
The other reason could be that any of your TypeA, TypeB or TypeC templates are being applied from within each other, which is a problem when you start by collecting all of them and applying templates to that result set (would return in duplicate renderings, possibly nested inside each other...)
When you refer to a "phantom" div (that should not exist and isn't defined anywhere) I'm guessing your actual problem i #1.
Anyways, show some of the actual code, and we can help you so much easier,
/Chriztian
Hi Gianluca, quick question about the extra <div>s ... where are you viewing these? Which browser are you using?
Are you viewing the "source" or the "rendered source"? Rendered source meaning via Firebug, or Chrome's Developer Tools? - if the HTML is invalid, these browsers will "fill in the gaps" and add tags to try to make it valid again. Just some food for though.
Cheers, Lee.
Reading your post I assume there must be some wrong formatted html code inside your template. As Lee mentions, which html are you looking at. Take a look at the real source code and try to find a possible error.
You can post html source code to w3c validators to check if every tag is closed properly.
Hello folks!
I really wish I could mark all of your answers as the correct ones, because they actually are!
Sascha, you were right. The problem were the empty DIVs. The code I wrote was meant to render some "boxes" that are located in a sidebar. Each box can have a title and/or a body. However, it is not mandatory to fill in the two fields. Hence when they were not populated, the xslt was generating an empty <div />, which was causing the issue. I simply verified that at least one of the two fields exists and is not empty, and that solved the problem.
And of course, Lee, you were right too. I am using Chrome, which has an integrated firebug-like tool. I like to look at the html/xml code in there, because it is more readable. However, as you pointed out, it "fills in the gaps"... whenever something is wrong, it tries to fix it by adding a tag that he believes to be the right one. I also tried to view the generated html code in firefox, and guess what? I was using firebug, which behaves in the exact same way. My fault: I didnt know that. And yes, actually looking at the "raw" source code (view source), it was kind of right; at least the divs were in the right position.
Nik, Chriztian, Folkert: thank you for your contribute as well!
I guess this is all.
Thank you once again.
Cheers,
Gianluca.
Hi Gianluca,
No worries about viewing the HTML in the Chrome Dev Tools/Firebug - I use them all the time, AND keep getting caught-out by the "rendered source" too! :-)
Glad you got it all sorted!
Cheers, Lee.
is working on a reply...