3

everyone!

I'm building a website based on some xml data files, so I chose to work with XSLT to bind the stylesheets in browsers.

It works quite good at first, but lately, as the templates grow more complicated, something strange happened.

I use the "copy-of" element to copy the data into the stylesheets. Here's the code:

<div class="section1">
    <xsl:copy-of select="article/bodydata/*" />
</div>

So, basically, I'm copying all child elements of the "bodydata" node into <div />.

But it doesn't work. For example, I've got an <img /> element in the bodydata, and that image does not appear if I visit the xml file in the browser. On the other hand, if I copy the "bodydata" elements by hand into that div, and make the .xsl file into a .html file, that image does show up.

So, here's my question, can I view the combined output of the xml data and the xsl data in browsers? Do I need any extension or what?

And any suggestions on what might be wrong? I'm quite new to xslt, so it seems that I misunderstood what XSLT really does. Thanks!

UPDATE

To illustrate the problem, I wrote a little sample.

First, I created a sample xml data file:

<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet type="text/xsl" href="article.xsl"?>
<article>
    <bodydata>
        <center>
            <img alt="sample" src="http://www.google.com/logos/classicplus.png" />
        </center>
        <p>
          <data class="tts_data">
          this is the paragraph.
          </data>
        </p>
        <p>
          <data class="tts_data">this is the second paragraph</data>
          <data class="tts_data">more data</data>
          <data class="tts_data">...</data>
        </p>
    </bodydata>
</article>

So, you can see, all nodes in "bodydata" element are html elements that needs to be show on webpage. In order to display that, I created a sample xsl file.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
      <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
          <meta name="robots" content="noindex" />
        </head>
        <body>
          <article>
           <header>
                  header of the article
               </header>
               <section>
                  <xsl:copy-of select="article/bodydata/*" />
           </section>
      </article>
          <footer>
          footer part of the page
          </footer>
        </body>
     </html>
    </xsl:template>
</xsl:stylesheet>

And the result is like this: the xslt result The img element just disappears.

And next, I copied the bodydata elements into the section part, and formed a new html file.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="robots" content="noindex" />
</head>
<body>
  <article>
    <header>
     header of the article
    </header>
    <section>
      <center>
        <img alt="sample" src="http://www.google.com/logos/classicplus.png" />
      </center>
      <p>
        <data class="tts_data">
        this is the paragraph.
        </data>
      </p>
      <p>
        <data class="tts_data">
        this is the second paragraph, 
        </data>
        <data class="tts_data">
        more data
        </data>
        <data class="tts_data">...</data>
      </p>
  </section>
    </article>
    <footer>
    footer part of the page
    </footer>
  </body>
</html>

And the result here is: the result of the html file And the image appears.

So I'm wondering what's wrong here.

10
  • What do you mean by "that image does not appear ..." Dont you see "<img ...>""? Or do you want to see the picture itself displayed? Commented Aug 14, 2012 at 12:14
  • @DimitreNovatchev I saw that img element in the dom tree, but the width and the height are all 0.
    – Void Main
    Commented Aug 14, 2012 at 12:15
  • this means that width and height are 0 in the source XML document (xsl:copy-of copies the nodes without any change). Therefore, to change the values of these attributes you should use something different than xsl:copy-of . Commented Aug 14, 2012 at 12:23
  • 1
    I am sure that if you provide a specific example (XML document( as small as possible) and specific requirements defining what output is wanted and the rules to produce the output from the input, then many people will be able to help. Commented Aug 14, 2012 at 12:28
  • 1
    <xsl:copy-of select="article/bodydata/*"/> doesn't copy the element bodydata itself -- only its children elements. However, you show that the bodydata has been also copied under div. This is a contradiction. It means that some other XSLT code is involved and you haven't shown this code. I am not sure if bodydata is a standard HTML5 element -- if not, it is likely that it and all its subtree is ignored by the browser. Commented Aug 14, 2012 at 12:48

2 Answers 2

3

Consider to show us minimal but complete samples to demonstrate the problem, otherwise it is hard to tell. xsl:copy-of sounds like the right approach to me, assuming the bodydata element has HTML elements as the child elements. As for looking at the transformation result, these days most browsers come with a developer tool (or you can install one like Firebug), then you can hit F12 to see the DOM tree of the document in the browser to inspect the result. As for an element copied to the result tree not showing up, in general it could be a namespace problem (i.e. copying HTML namespace-less img to XHTML result document). So show us more details as to which browser(s) you have tried, which output method your XSLT has, which version of HTML you are trying to create as the transformation result (i.e. HTML 4.01, XHTML 1.0, HTML5).

[edit] With your current samples where you use a root element named html in the XHTML 1.0 namespace for the result tree, Firefox/Mozilla render your result as XML where namespaces matter. When you copy the img element from the input XML you copy an img element in no namespace into an XHTML document, so due to the lack of the right namespace on the img element the browser does not recognize the img element as an XHTML img element. So you either need to change your input XML to use the XHTML namespace for the fragments of (X)HTML you want to copy, or, in my view these days with the focus being on HTML 4 or HTML5 with no namespaces, you simply use that version of HTML in the result tree of the stylesheet i.e. you don't use a namespace for the document's root element, you set <xsl:output method="html" version="4.01"/> or <xsl:output method="html" version="5.0"/>. That way the problem should go away.

As an alternative, if you really want the result to be XHTML but you want to copy an XML img element in no namespace into the XHTML result tree, the proper way would be not to use copy-of, instead you would use <xsl:apply-templates/> and then you would need to write templates that transform the elements you need into the XHTML namespace e.g.

<xsl:template match="img | p | center">
  <xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml">
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

In my view with all browser vendors focusing on HTML5 without namespaces I would however suggest not to transform to XHTML and instead target HTML 4.01 or HTML5 without namespaces, you get better cross-browser interoperability with XSLT 1.0 in the browser.

5
  • I've tried in Safari, Chrome, Firefox. All with the same behaviour.
    – Void Main
    Commented Aug 14, 2012 at 12:27
  • And I've uploaded a screen shot from Safari.
    – Void Main
    Commented Aug 14, 2012 at 12:33
  • Please show us details of the code in particular the xsl:output element (if any) in the stylesheet, the name and namespace of the root element the XSLT creates. Commented Aug 14, 2012 at 12:52
  • Hi martin, I've made a sample above. Thanks for your help.
    – Void Main
    Commented Aug 14, 2012 at 13:02
  • You are right, it's a problem with the output element. Thank you!
    – Void Main
    Commented Aug 14, 2012 at 23:53
1

I get the full wanted result when I display the XML file with IE9:

enter image description here

Update:

As shown by Martin Honnen, the missing xsl:output statement causes output method xml (default) to be used and this is what causes the browsers not to treat the output as HTML.

Adding <xsl:output method="html"/> solves the problem.

5
  • I just tried -- FF shows only text. Chrome shows a blank page -- both these browsers have a similar bug in their inability to perform an XSLT transformation. Commented Aug 14, 2012 at 14:07
  • I don't think it is a bug, I think the problem is a difference in the type of the transformation result and the namespace handling. With the samples as currently posted the root element of the result tree is an XHTML html element, so the output method is xml where namespaces matter. And the img element copied over from the XML input to the result tree is in no namespace, that way Firefox when rendering XHTML as XML does not recognize the img element in no namespace. So to fix the problem in a cross-browser way I would suggest to use HTML 4.01 or HTML5 for the result document. Commented Aug 14, 2012 at 14:13
  • <xsl:stylesheet version="2.0" xmlns:xsl="w3.org/1999/XSL/Transform">(replace 1.0 to 2.0) <xsl:output method="html" indent="yes"/> and it works!
    – Void Main
    Commented Aug 14, 2012 at 23:53
  • @VoidMain, Yes, that is even better -- I didn't pay attention to the xsl:output element. I don't think version="2.0" helps in this case -- have you tried with version="1.0" ? Commented Aug 15, 2012 at 1:48
  • @DimitreNovatchev, you are right, the version number does not matter.
    – Void Main
    Commented Aug 15, 2012 at 9:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.