Implementing the XSLT Mediator – Part 2

18 thoughts on “Implementing the XSLT Mediator – Part 2”

  1. hi,
    i am working with latest version of sdl tridion 2009. i want to change the component using TOM.net api.

    Example: i have a schema that has field Name. & i created a component called Person. using tom.net i want to change the value of Name field.
    can you help me out how can i do that.

    also .
    1. how can i connect to the Tridion system to generate a session object
    so that i can do following

    Component myComponent = (Component)mySession.GetObject(“tcm:1-8”);
    ItemFields contentFields = new ItemFields(myComponent.Content, myComponent.Schema);
    TextField myTextField = (TextField)contentFields[“MyTextFieldName”];
    myTextField.Value = “New Value”‘;

    1. HI Chandra,

      Thanks for reading my blog.

      To answer your questions:

      1. Changing values with TOM.NET: Im afraid this is not possible still with the latest version of Tridion. the TOM.NET API is still read-only. This will be changed with the next release(2010).

      2. To be able to modify items in Tridon from code you will need to use the interops for .NET. you can find these in the Tridion installation folder and then: Bin/Client/PIA.

      You can then write something along these lines:

      using Tridion.ContentManager.Interop.TDS;
      using Tridion.ContentManager.Interop.TDSDefines;
      .
      .
      .
      TDSE tdse = new TDSE();
      tdse.Initialize();

      Component myComp = tdse.GetObject(“tcm:1-8”, 2, null, XMLReadFilter.XMLReadAll);

      myComp.Fields[“fieldName”].value[1] = “New Value”;

      myComp.Save(true);
      .
      .
      .
      The entire COM API (the one used by the interops) is documented in the Templating and Customization Manual TOM 2009.chm.

      Let me know if i can be of more help.

      Dont forget you can ask questions and get more information on our forum: https://forum.tridion.com and find great stuff on http://www.sdltridionworld.com

  2. Hi yoavniran, chandra
    I want to access Image using above mycomp.Fields[] way.
    Can i get the System.Drawing.Image from the component using above.
    if yes how
    if no please tell what can be done.

    how can i get the image. can you give some pointers.

    Thanks a lot.

    1. Hi there,

      If you want to get the image binary data you can do the following:
      using the .NET interops:
      Image image = Image.FromStream(new MemoryStream(comp.Multimedia.GetBinaryContent()));

      using the TOM.NET API:

      Image image = image.FromStream(new MemoryStream(comp.BinaryContent.GetByteArray()));

      If you need this functionality to for example publish thumbnails of your images on the fly, make sure you check out the documentation for using the AddBinary method and variants so Tridion will manage the publishing and un-publishing of the thumbnails in your templates.

  3. Hey Yoavniran, a lot of thanks for your help.

    i have another question if you can help,
    I was trying using normal XSLT component template(CT). My component contains some multimedia object. I want the image path or video path in the XSLT. Is it possible with the normal XSLT without using Compound template,
    Can you help me out.
    Regards
    Raj Mittal.

    1. Yes, you can.
      If you create a normal CT and change the type to XSLT.
      Then you need to declare the Tridion script assistant namespace like so:

      xmlns:tcmse=”http://www.tridioncom/ContentManager/5.1/TcmScriptAssistant”

      Then in your templates you can use the assistant’s exposed methods, one of them is of course PublishBinary:

      I believe you can also use the AddBinary method and even pass the SG URI like so:

  4. We’re using the XSLT mediator in one of our projects to output asp.net pages. These pages contain asp.net tags and custom tags. When outputting an asp.net tag, the resulting tag always contains a namespace declaration, for instance: xmlns:asp=”remove”.

    I’ve modified the XSLT Mediator code to remove all the namespaces containing the word “remove” using a regex. When previewing the page in the Tridion GUI or in template builder, these namespaces are indeed removed. However, the actual published page on the webserver still contains these namespaces.

    Any ideas on how to get rid of these namespaces?

  5. Hi yoavniran,

    I followed the same steps that explain above.
    I am trying to use

    But it is throwing error “Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.”

    Can you please suggest where I am doing wrong?

    Also I am expecting XHTML output from this method, the same way I am getting on TBB using DWT.

    Thanks

  6. Hi there Piyush,

    Sorry to hear you’re having difficulties. Can you please post the stack trace that is outputted with the error.
    Also try using a very simple XSLT, one that only outputs a single text field just for testing and see whether that makes a difference.

    The default output type for the Mediator is XHTML and you can also control the output type using the parameters schema that I included in the downloadable zip file on SDLTridionWorld.

    Yoav.

  7. Hi Yoavniran,

    The method that I am trying to use from the above code is RenderComponentPresentation which is returing XMLDocument as per the above code, But I am expecting XHTML output from this method.

    Even when I am using the same method and call on XSLT it is throwing error as below:

    (2147747185) Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 1, position 207.
    Unable to get rendered content of Component Template (tcm:6-283-32).
    Unable to retrieve rendered data from Component Presentation.
    An error occurred during a call to extension

    Please help me to resolve this problem.

    Thanks.

  8. Hi again,

    The RenderComponentPresentation method is actually causing a render of your component template which can be written in XSLT as well or .NET or Dreamweaver.

    I would suggest debugging your component template in the Template Builder and see whether its output is actually valid XML (XHTML) and also doesnt include the xml declaration node since its going to be embedded inside the page output.

    Good luck.

  9. Hi yoavniran,

    Firstly, thank you for the XSLT Mediator and the accompanying documentation. It has helped make my templates simpler by reducing the number of custom .NET building blocks needed per compound template.

    I was wondering if it is possible to remote debug the .NET extension functions called from within an XSLT template? Similarly to how I can attach Visual Studios to the server’s TcmTemplateDebugHost.exe and step through my .NET building block code. Attaching to the TcmTemplateDebugHost.exe does not seem to work, is there another process that I should use?

    Thanks again,

    Eric

    1. Hi Eric,

      Im glad to hear that the article has been helpful to you.

      I never actually managed to get VS to debug my XSLT extensions when they are called from templates. The problem is I think is that the extension objects are loaded at run time from Tridion.
      What you could try doing is if you are on the CM server, try to attach VS to the publisher service and actually publish the item, this might work but Im not sure.

      Good luck 🙂

  10. Hi Yoav,

    Posted this comment before in part 1 of this series.

    I’ve created my own custom XSLT helper class from the IXSLTHelper interface. The helper is loaded from the .NET assembly stored in Tridion. This works great in Template Builder and when publishing items. However, when I do a preview in the GUI I get the following error:

    “Cannot find the script or external object that implements prefix ‘http://www.tridion.com/xslthelper’.”

    The namespace here is the one I used for the ‘TridionXSLTHelperNS’ attribute.
    It appears that the “GetHelpersFromTridion” method is not getting called (or fails) when using preview mode. Have you seen this error before? Any ideas on how to fix this?

  11. Hi Yoav,

    Can you please suggest what can be the reason for below error.

    I am passing my outputted string xml to the attached xslt in my template builder. I am getting below error:

    Cannot find the script or external object that implements prefix ‘http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant’.
    at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, IList`1 navConfig)
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
    at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator )
    at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
    at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
    at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
    at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XsltArgumentList arguments, XmlWriter results, XmlResolver documentResolver)
    at Tridion.Extensions.Mediators.XsltMediator.Transform(Engine engine, Template template, Package package)
    at Tridion.ContentManager.Templating.Engine.ExecuteTemplate(Template template, Package package)
    at Tridion.ContentManager.Templating.Engine.InvokeTemplate(Package package, TemplateInvocation templateInvocation, Template template)
    at Tridion.ContentManager.Templating.Compound.CompoundTemplateMediator.Transform(Engine engine, Template templateToTransform, Package package)
    at Tridion.ContentManager.Templating.Engine.ExecuteTemplate(Template template, Package package)
    at Tridion.ContentManager.Templating.Engine.InvokeTemplate(Package package, TemplateInvocation templateInvocation, Template template)
    at Tridion.ContentManager.Templating.Engine.TransformPackage(Template template, Package package)
    at Tridion.ContentManager.Templating.Engine.TransformItem(Template template, IdentifiableObject itemToRender)
    at Tridion.ContentManager.Templating.Debugging.DebuggingEngine.Run()
    at Tridion.ContentManager.Templating.Debugging.DebugSession.Run()

    1. Hi Manoj,

      Looks like you copied that XSLT from a old-school xslt TBB and it still has a reference to the script assistant which the XSLT Mediator has no notion of. You should remove that namespace: ‘http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant’. and try again.

      Yoav.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s