Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Gianluca 56 posts 79 karma points
    Jul 14, 2010 @ 18:52
    Gianluca
    0

    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:

    <head>...</head>
    <body>
       <div id="container">
          <div id="header">...</div>
          <div id="content">...</div>
       </div>
       <div id="footer">...</div>
    </body>

    Well, with the XSLT on, the "footer" is moved inside "container"!!! 

    Is there any reason why this is happening?!? 

    Thanks in advance,

    Cheers,

    G.

  • Sascha Wolter 615 posts 1101 karma points
    Jul 14, 2010 @ 19:09
    Sascha Wolter
    0

    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

  • Nik Wahlberg 639 posts 1237 karma points MVP
    Jul 14, 2010 @ 19:13
    Nik Wahlberg
    0

    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:

    <xsl:output method="xml" omit-xml-declaration="yes" />

    vs.

    <xsl:output method="html" omit-xml-declaration="yes" />

    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

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jul 14, 2010 @ 21:05
    Chriztian Steinmeier
    0

    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.:

    <div>
        <xsl:value-of select="something/that/could[@render = 'nothing']" />
        <xsl:comment /><!-- Prevent self-closing element -->
    </div>

    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

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Jul 14, 2010 @ 21:18
    Lee Kelleher
    0

    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.

  • Folkert 82 posts 212 karma points
    Jul 15, 2010 @ 10:08
    Folkert
    0

    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.

  • Gianluca 56 posts 79 karma points
    Jul 15, 2010 @ 11:05
    Gianluca
    1

    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.

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Jul 16, 2010 @ 10:15
    Lee Kelleher
    0

    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.

Please Sign in or register to post replies

Write your reply to:

Draft