0

I am new to XML (a couple of days now...)and everything is going good, however, I can't seem to get the xml processed with css style

here is my perl...

#!/usr/bin/perl -w

use strict;
use warnings;
use diagnostics;
use Text::CSV_XS;

my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 });
my $ifile="elementarray.csv";
my $ofile="elementarray.xml";
open my $fh, "<", $ifile or die $ifile.": $!";
open my $out, "> ".$ofile or die "Cannot write ".$ofile.": $!";

print $out <<EOT;
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="elementarray.xsl"?>
<?xml-stylesheet href="elementarray.css" title="Default style"?>
<EMAILCOMMENTS>
EOT

# First record contains list of fieldnames
#my $fields = $csv->getline($fh);
#print @$fields;
while (my $row = $csv->getline($fh)) {

    last unless $row && @$row;

    # Encode "<" characters as "&lt;" and "&" as "&amp;" in all fields
    foreach (@$row) {
    s/&/&amp;/g;
    s/</&lt;/g;
    }

    # Create hash of fields using hash slice
    my %row;
    @row{"Subject","Body","From: (Name)","From: (Address)","To: (Name)","To:(Address)","Date","Time"} = @$row;

    print $out <<EOT;
    <EMAIL>
    <HEADER>
        <ORIGNAME>$row{"From: (Name)"}</ORIGNAME>
        <ORIGADDRESS>$row{"From: (Address)"}</ORIGADDRESS>
        <DESTNAME>$row{"To: (Name)"}</DESTNAME>
        <DESTADDRESS>$row{"To: (Address)"}</DESTADDRESS>
        <SUBJECT>$row{"Subject"}</SUBJECT>
    </HEADER>

    <BODY>$row{"Body"}</BODY>
    <DATE id="date">$row{"Date"}</DATE>
    <TIME id="time">$row{"Time"}</TIME>
    </EMAIL>
EOT
}
print $out "</EMAILCOMMENTS>\n";
$csv->eof or $csv->error_diag;
close $fh or die $ifile.": $!";
close $out or die $ofile.": $!";

Here is my xsl...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes" method="html"/>
    <xsl:template match="/"><!-- a 'pattern', / matches the root node -->
        <html>
            <head>
                <title>E-mail</title>
            </head>
            <body>
                <xsl:apply-templates/><!-- an instruction -->
            </body>
        </html>
    </xsl:template>
    <xsl:template match="HEADER">
        <span STYLE="color:red; font-weight:bold; font-style:italic">
            <xsl:value-of select="SUBJECT"/>
        </span>
        From: <xsl:call-template name="formatEmail">
                <xsl:with-param name="address" select="ORIGADDRESS"/>
              </xsl:call-template>
        To: <xsl:call-template name="formatEmail">
                <xsl:with-param name="address" select="DESTADDRESS"/>
            </xsl:call-template>
    </xsl:template>
    <xsl:template match="EMAIL">
        <xsl:apply-templates select="HEADER"/>
        <pre>
            <xsl:value-of select="BODY"/>
        </pre>
        <div>
        <span>
        <xsl:attribute name="id"><xsl:value-of select="date"/></xsl:attribute>
        <!-- --><xsl:value-of  select="DATE"/><!-- --></span>
        <span>
        <xsl:attribute name="id"><xsl:value-of select="time"/></xsl:attribute>
        <!-- --><xsl:value-of  select="TIME"/><!-- --></span>
        </div>
    <br />
    </xsl:template>
    <xsl:template name="formatEmail">
        <xsl:param name="address"/>
        <a>
            <xsl:attribute name="href"><xsl:value-of select="concat('mailto:',$address)"/></xsl:attribute>
            <xsl:value-of select="$address"/>
        </a>
    </xsl:template>
</xsl:stylesheet>

here is my xml (1 record)...

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="elementarray.xsl"?>
<?xml-stylesheet href="elementarray.css" title="Default style"?>
<EMAILCOMMENTS>
    <EMAIL>
    <HEADER>
        <ORIGNAME>William Holt</ORIGNAME>
        <ORIGADDRESS>&lt;[email protected]></ORIGADDRESS>
        <DESTNAME>X</DESTNAME>
        <DESTADDRESS>[email protected]</DESTADDRESS>
        <SUBJECT>welcome to the neighborhood</SUBJECT>
    </HEADER>

    <BODY>just thought i'd say hello</BODY>
    <DATE id="date">07/18/2013</DATE>
    <TIME id="time">11:53</TIME>
    </EMAIL>
</EMAILCOMMENTS>

and here is css ( style for just to see if it is working, and it isn't :( )...

DATE{background-color:red;}
TIME{background-color:green;}
#date{background-color:yellow;}
#time{background-color:blue;}
BODY{background-color:grey;}

Sorry for the length of the post but I think you need all these files...

1
  • What are you expecting to happen? XSLT has no awareness of CSS. Commented Aug 10, 2013 at 15:49

1 Answer 1

1

Although you can indeed style XML with CSS, using the xml-stylesheet processing instruction you have included in your XML, you can't transform it with XSLT at the same time. That is to say you should only really have one stylesheet processing instruction in your XML. Either you simply style your XML with CSS (which is not really a common thing to do), or your transform it to HTML with XSLT and style the HTML output with CSS.

In the latter case, remove the <?xml-stylesheet href="elementarray.css"?> instruction from your XML document, and instead output a reference to the CSS document in your first template.

<xsl:template match="/">
    <html>
        <head>
            <title>E-mail</title>
            <link href="elementarray.css" type="text/css" rel="stylesheet" />
        </head>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

Now, in your CSS, I see you already have selectors for the date and time ids, so you need to ensure the relevant elements in your HTML have these ids.

At the moment, you are doing this in your XSLT

    <span>
    <xsl:attribute name="id"><xsl:value-of select="date"/></xsl:attribute>
    <!-- --><xsl:value-of  select="DATE"/><!-- --></span>
    <span>

But this is setting the id attribute to have the value of the date element in your XML, but such an element does not exist! I think you meaning to use the literal string here. Now, you could do this...

<xsl:attribute name="id"><xsl:value-of select="'date'"/></xsl:attribute>

But this is verbose. You can just do this:

<xsl:attribute name="id">date</xsl:attribute>

But better still, just write it out as an attribute in the normal way:

   <span id="date">
       <xsl:value-of  select="DATE"/>
    </span>

And similarly for 'time'. This should ensure the two span tags get styled using your CSS in the HTML you output.

Sign up to request clarification or add additional context in comments.

1 Comment

I did not know that... I was going over someone else's work which had a both a link to xslt and css... now I know, thank you very much for the alternative views that was very helpful

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.