www.netsi.dk

"The internet is just a layer on the real world" (don't forget that!)

XSLT transformation on Mac OSX

The startup screen of Transform

As I am now on Mac I am on a constant search for the tools I miss from my time on Windows. I do some offline transformation as I implement websites in for instance .

I often get the XML from the CMS, download it and build the XSLT to transform the raw XML into HTML. Back in the old days where I used Visual Studio every day on Windows I could do XML transformation in there, I could also single step and more nice stuff.

On Mac I use Sublime Text which I have found such an option for – so I tried to search the Apple App store for a tool to help me. I discovered “Transform” by Niel Ang which has it advantages. I will update this blog post with more notes about the product as I discover them. For now I have discovered this:

* Works dynamically and reacts to file changes
* Works with files, so it can be used with any editor
* Has a preview option (of transform result), I have not yet found out how to do this, which is due to my rather thin knowledge about running a web server on my mac.
* As with other purchased apps you may use it on more than one device

You can find information about the product here: http://neilang.com/transformapp/ where there is also a link to appstore. I find the price 32 DKK / 5 $ an okay price.

Share

Controling styles for individual websites by adding extra classes to HTML tag

When working with like or Syncron VIA, you sometimes share files across domains or subdomains. It makes sense to share common codes when you want to some some common styles like fonts, colours or logos.

 

The same styles… almost…

It is also common that some small differences exists on subdomains, perhaps a campaign site or a site target for a specific group of people. You then need to apply some small changes to those sites. Ofcause you can do this in many ways, and the CMS you use will probertly be a part of your decision on how to implement it. Here is one way to do it:

Add a CLASS to HTML tag with some site related information.

For instance I could add this to my blog:

<html class="wwwnetsidk"...

The rule should be simple, for instance:

  • Replace not-valid characters like “.” from the DOMAIN NAME to “nothing”

The reason it should be simpel is that it makes it easy to figure out what it should be for a given domain name. Things which are using the KISS (“Keep It Simple, Stupid!”) principle will more likely be used by people, as (in general) people are lazy (I know! Smiley, trust me.)

 

When this rule have been applied you can add extra lines to your shared CSS file like this:

html.wwwnetsidk {background-color: red;}

The princip is used widely, for instance by http://www.modernizr.com/ which addes a lot of feature related classes to your HTML element telling you for instance which HTML5 features are supported. Just look here at parts of what modernizr adds to your HTML document:

js no-touch postmessage history multiplebgs boxshadow opacity...

Dynamicweb CMS

Working with Dynamicweb CMS, here is an example of adding extra information to HTML element – “areaid-xx” will add the ID of the area. In Dynamicweb you can have several areas, which are individual websites. So you might have areaid=1 which is www.netsi.dk and areaid=2 which is m.netsi.dk. In the example below I have also added extra information telling if the person is a returning person.

<html class="areaid-<!--@Global:Area.ID-->
<!--@If Defined(Global:OMC.Visitor.IsReturning)-->IsReturning<!--@EndIf(Global:OMC.Visitor.IsReturning)-->"...

You may add any information you wish, perhaps have a look at the tags that Dynamicweb CMS offers.

Syncron Via CMS

Here are an example of how I have implemented this feature in the Danish CMS system Syncron Via. The system is using a lot, and the code here is applied to the template used to render the outer Page data:

<xsl:variable name="serverName" select="translate(/Page/RequestContent/ServerVariables/Entry[@Name='SERVER_NAME'], '.-', '')" />
...
<html class="{$serverName}"...

This is what I do: define the class to be added to the HTML element in a variable and add it to the HTML class attribute.

Share

Did you remember to exclude namespaces from output?

When you work with , transforming XML to for instance the web in some system, you might use some extra namespaces. Perhaps the offers you some utilitiy to handle relevant datastructure or procedures. You add them to your XSLT but perhaps you forgot to tell the XSLT processor not to add the namespaces to the output? Well I do some times…

 

Namespaces in a XSLT template

Adding namespaces to get extra features in your XSLT is easy. You may or may not think about it, but you will allways add at least one namespace “xsl”. Using Microsoft Visual Studio and selecting “New XSLT…” you will probertly also get a MS namespace like this: “msxsl”. I all happens in the beging of the template like this:

<xsl: version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl "
  xmlns:cs="urn:custom-cs"
>

In the above example there are three namespaces:

  • xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  • xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  • xmlns:cs="urn:custom-cs"

The first one “xsl” is telling the XSLT processor that we are using XSLT and that the we will be using the XSLT rules defined in 1999 by w3.org.

The next one “msxsl” addes MS custom features and will give you some nice new features, for instance functions to format dates (ms:format-date Function).

The last one I use for adding custom in my XSLT. That is a very powerfull way of extending the XSLT processor with your own custom .NET . But please take care when doing that!

 

Removing the namespace from the output

If you use custom namespaces you may end up with the namespaces added to the output elements. In the above code you may observe that there is an attribute “exclude-result-prefixes” on the xsl:stylesheet tag. It is used to tell the XSLT processor which namespaces should not be added to the output elements. I have added “msxsl” but not “cs”. I the example I use XSLT in CMS to generate HTML, so I may get output looking like this:

<ul xmlns:cs="urn:custom-cs">

That is not what I wanted! To remove the “cs” namespace I simply need to modify the xsl:stylesheet attribute “exclude-result-prefix” to:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl cs"
  xmlns:cs="urn:custom-cs"
>

I have added the “cs” namespace, so I will now get a tag without the “cs” namespace in my HTML.

Share

Using XPath operator “//” aka “descendant-or-self” in XSLT

In my daily work as developer at www.bleau.dk I do a lot of “programming” – is one of the things you need to master most. With the focus mainly set on closing tasks I have not had the time to test a – well nice to know thing with the “” XPath . Tonight I finally found out what had been a question in my mind for at long period:

The “//” (decendant-or-self) XPath operator: Can it be used relative inside a full XPath? Will it “search” from the Document top, or start where it is placed inside the XPath selector?

An example XML:

<?xml version="1.0" encoding="utf-8"?>
<people>
  <group type="frontEnd">
    <person name="Sten" />
  </group>
  <group type="backend">
    <person name="Sten" />
  </group>
</people>

The two XPaths

//person[@name='Sten'] – Returns a nodeset containing 2 elements

//group[@type="frontEnd"]//person[@name='Sten'] – Returns a nodeset containing only 1 element

So as you can see the first one looked from the root (/People) and anywhere inside the document. The second one had the “//” inside a XPath, which in made the “//” operator look from the spot it was and below.

Conclusion

Well, I just got a litle wiser as I learned that I actually can use the “//” operator inside XPath selectors.

Links
Share

Using C# in XSLT – part 2: A remoteHTTP request

In this part of my in series of posts, I will show an example of making a basic remoteHTTP request from some inline C# embedded inside a . We will fetch a RSS feed from CNET.com and display it in a simpel UL list. The post transformations have been done using Microsoft Visual Studio.

A remoteHTTP request

You probertly know what a remoteHTTP request is, even if you have never heard about by that name. Every time you enter an URL you actually do a HTTP request. You point to an URL and get “something” back. In this post we will do just that, but from within some C# code being executed in the context of a XSLT transformation.

The result – effect – is that we can expand the XML which the XSLT can transform! Actually we only need a basic XML document to start up with – the actual XML is fetched from a remote site using the remoteHTTP request. So imagine that you have some XML which comes from a system – say – you then need to fetch a RSS feed containing news from CNET.com and output an UL list with the news items on the webpage. We need some C# method to do the job for us…

The C# remoteHTTP method

Below you can see a screenshoot of the C# remoteHTTP method (you will find a link to a ZIP file containing the source code of this and the other files at the bottom of this page).

C# remoteHTTP method

I will not say more about this code, other than I have added som basic Exception handling, returning a DOM tree with exception details (StackTrace, Message, Source, URL).

Here are some things I suggest when coding your C# code for use in XSLT:

a) In Visual Studio create a C# web project. In a “dummy” class add create the methodes and thereby getting intellicense and syntax check of the C# code.

b) Surround your code with try-catch error handling, things will go wrong at some time, so why not be prepared for it to happen?

c) Adding your XSLT file to the same project, you in practice have one structured container for both the syntax-validated methodes (classes at a later time!) and your XSLT stylesheets!

Preparing the XSLT stylesheet for inline C# code

To be able to make use of C# methodes from XSLT you need to do three things other than coding your C# code:

1) Add the namespaces and references making it possibel to execute C# code

The start of the XSLT template

We  need to declare two namespaces for “urn:scemas-microsoft-com:xslt” and “urn:custom-cs”. At the same time I do not wish to return any elements with that , so I add it to the “exclude-result-prefixes” of the stylesheet element.

2) Insert the C# code with the needed C# namespaces and assemblies

The XML element containing the C# code
Within the msxsl namespace the “script” element is used. As you might guess C# is not the only supported language. I am not sure exactly which languages are supported, but jscript.net is supported. Normally I prefer , but in this case I think that C# is best, as there are more help when doing the coding i the web project class. Actually I think that Microsoft is doing very little to support jscript.net.

3) Executing the C# and recieving the result

Calling the C# methode from XSLT Above you see in line 60 how I call the remoteHTTP C# method:
cs:remoteHTTP('http://news.cnet.com/2547-1_3-0-20.xml')

In our example we define a variable called “feed”, and it will contain the XMLDocument which is located at the URL at http://news.cnet.com/2547-1_3-0-20.xml. It is a valid RSS 2.0 news feed, and the result will be a 100% valid XML DOM tree. With that we can do any kind of normal XSLT transformation – as you can see in line 75. Here I select the child element “rss” of within the variable ($feed). We have succeded in fetching an external RSS feed from within a XSLT stylesheet – allowing us in a very dynamic web to execute .NET code based on dynamic values!

As I mentioned in the first post “Using C# in XSLT transformations – Very strong tool!” I will be writing about the pros and cons when using this approach, so far I have been very positive, but ofcause nothing comes from free! There is a price to pay – more about that in a later post. For now: Enjoy this “new” way to enrich and add power to XSLT! I do!

You may download ZIP file using the link below, it contains a visual studio project which contains all the files you need, and a SIMPEL how-to page:

  • testXML.xml
    Basic XML file which you can point to as your source XML file from Mictosoft Visual Studio when doing the transformation.
  • remoteHTTP.xslt
    The XSLT stylesheet containing the C# code
  • remoteHTTP.htm
    An example output of a transformation done in Mictosoft Visual Studio
  • remoteHTTP.cs
    A C# class which I used for coding the C# code

Source files from this post

Links
Share

Using C# in XSLT transformations – Very strong tool!

When I build websites in I use . At the moment it is based on XSLT 1.0 which in its XSLT nature ofcause is much stronger than HTML based , but somehow limited compared to all the nice features which are defined in XSLT 2.0.

You may however extend to the extreme the facilities by using in XSLT! I will start writing about the things I discover in this direction, writing about pros and cons. For now I wil not give any concrete examples, only mention that I have made an XSLT templates which gets a RSS feed (does a remoteHTTP request) and displays the transformed contents on a Dynamicweb page! Very cool! Something which I actually could not do without having to my own Dynamicweb module!

It Rocks and I will start to think this into future templates – taking into account ofcause the pros and cons of that path!! This might just prove to be the best christmas present in the IT area of my life, this year!

Share

Javascript i XSLT – et gode eller et onde?

Jeg har en del viden indenfor og nu hvor også er noget jeg arbejder med er det åbenlyst at kombinere disse to teknologier.

Jeg har dog kollegaer der mener at det er en dum ide – at blande disse to ting. De mener at når man transformerer data så er man ude i “view” delen af Model View Control løsning, og der skal der ikke være kode (udover XSLTen).

Jeg kan godt se at de har lidt ret, men mener på den anden side at man bare udvider de ting som XSLT kan. Hvis man sørger for at have solid javascript kode og kun benytter den som en støtte til allerede eksisterende XSLT funktionalitet kan der ikke være noget galt i det.

Hvad synes du?

Eksempler på sider der omhandler emnet:

Share

Getting the right contents when using Dynamicweb CMS templates

In the system I work with – Dynamicweb CMS – content is build around various , each containing a output from the system. The output is generated using ASP.NET and each bit of content is represented in a “tag”. For instance if you want the name of the user which has logged on the page you enter

<!—@Global:Extranet.Name-->

Such templates are based on HTML, it is: You create static parts of HTML and insert tags where you want the system to insert dynamic content.

You might want to do something like this:

...<div>Hi <!—@Global:Extranet.Name-->!</div>...

So far so good! But what if the user has not logged in? You will need to do one of three things:

The soloution

Put shortly: Using javascript to control which content is shown is basically not a good idea. But today almost anyone browsing the net has javascript turned on, and the trend (IMHO) goes towards very powerfull javascript parts. Another discussion is that: “Why give a visitor contents if you allready before you start sending information (HTML) that the content is not really relevant?”. Well, another article about that.. :-) Here goes:

...<script type="text/javascript">
if ('<!—@Global:Extranet.Name-->'!='') {
document.write('<div>Hi <!—@Global:Extranet.Name-->!');
}
</script>...

The soloution

This is actually not a way which I would say always works! But the theory is that you put CSS classes  on HTML tags that are build around a classname-prefix (“customerNumber” for instance) and then add the dynamic value from CMS as postfix. So if a user has logged in a classname would be for instance “customerNumber342” for a customer with the number 342. A customer who has not yet logged in would give a classname “customerNumber”. So if we by default hide the classname “customerNumber” any other classnames would be displayed! :-) Cute right? But the problem can rise when sometime certain Dynamicweb are not replaced, even if it has no value. That way you might end up with

“customerNumber<!--@Global:Extranet.CustomerNumber-->”

That would even be invalid HTML! :-( Anyway here is how a CSS based soloution could be.

<head>.. <style type="text/css">
.customerNumber {display: none;}
</style>
..
</head><body>
...
<div class="customerNumber<!--@Global:Extranet.CustomerNumber-->">
Hi <!—@Global:Extranet.Name-->!
</div>

The If Defined soloution

Dynamicweb CMS offers a way to check if a tag has content, and only pass the  content within the IF-ENDIF if a tag has content.

<!--@If Defined(Global:Extranet.Name)-->
<div>Hi <!—@Global:Extranet.Name-->!</div>
<!--@EndIf(Global:Extranet.Name)-->
...<div>Hi <!—@Global:Extranet.Name-->!</div>...

These are just 3 ways of making workaround in Dynamicweb CMS, you could ofcause come up with more! For instance combining the javascript and CSS soloution.

Templates comes to our rescue – well almost!

Imagine that you build your content using XSLT: Dynamicweb CMS will build a XML document containing all the “template tag values” in a structured way. A tiny bit of this XML document might be:

...<Global.Extranet.Name>342</Global.Extranet.Name>...

So this way you decide if it is relevant to produce output based on “real” values! You can use the power of XSLT/ to decide what to do. An example:

<xsl:if test="Global.Extranet.Name!=''">
<div>Hi <xsl:value-of select="Global.Extranet.Name" />!</div>
</xsl:if>

All this is done before the content has been send to the client (in Dynamicweb Backend). It is a clean powerfull way to produce exactly what is needed for the page to render as wished.

Nothing is perfect…

When all this is said, I must warn you: The XSLT templates path is – I am sad to say – not always perfect in Dynamciweb CMS. The XML document does not always have all tags. I have some workarounds which I will write about in a later article.

You can see all template tags at templates.dynamicweb.dk.

Share