4

I'm making a component template by using XSLT TBBs. The template contains 1 C# TBB and 2 XSLT TBBS(XSLT1 and XSLT2). What my template doing is following.

  1. C# TBB generate XML and push it to package
  2. XSLT1 TBB get the XML from package, and push transformed XML to package.
  3. XSLT2 TBB get the XML(transformed by XSLT1) from package, and push transformed XML to package.

But following error occurs on XSLT2.

There Is No Unicode Byte Order Mark. Cannot Switch to Unicode.

I noticed that encoding of XML item pushed by XSLT1 is "utf-16" regardless of XSLT1 specifies encoding="utf-8" on xsl:output element. How can I use XSLT TBB by this way?

My source codes are following:

C# TBB

 class TestXMLTBB:TemplateBase
    {
          public override void Transform(Engine engine, Package package)
          {
              string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><root><element>value</element></root>";
              package.PushItem("TestXML1", package.CreateStringItem(ContentType.Xml, xml));
          }
    }

XSLT1

<?xml version="1.0" encoding="utf-8"?>
<?XsltMediator inputItemName="TestXML1" outPutItemName="TestXML2"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xlink="http://www.w3.org/1999/xlink" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />
      <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

XSLT2:

<?xml version="1.0" encoding="utf-8"?>
<?XsltMediator inputItemName="TestXML2" outPutItemName="TestXML3"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xlink="http://www.w3.org/1999/xlink" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />
      <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

I revised C#, but same error occurs. Revised source code is following.

  class TestXMLTBB:TemplateBase
    {
          public override void Transform(Engine engine, Package package)
          {
             MemoryStream stream = new MemoryStream();
             XmlDocument d = new XmlDocument();
             XmlTextWriter writer = new XmlTextWriter(stream, new UTF8Encoding(false))
             {
                 Indentation = 4,
                 Formatting = Formatting.Indented
             };

            writer.WriteStartDocument();
            writer.WriteStartElement("root");
            writer.WriteStartElement("element");
            writer.WriteValue("value");
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
            stream.Position = 0;

            package.PushItem("TestXML1", package.CreateStringItem(ContentType.Xml, Encoding.UTF8.GetString(stream.ToArray())));
          }
    }

Regards,

1
  • It would appear the problem occurs in the XSLT mediator and not in your code; are you using the XSLT mediator or are you using custom C# code to perform the XSLT transform and store the result? If so please list that code as well... Apr 16 '15 at 13:50
2

This is how I would normally create a XML object in the package:

package.PushItem(Package.OutputName, package.CreateStringItem
                (ContentType.Xml, Encoding.UTF8.GetString(stream.ToArray())));

And I would normally use a MemoryStream and XmlTextWriter (link to full example below). This would ensure that not only the XML document states it is UTF-8, it actually really is UTF-8.

As you noticed, by default Tridion will use UTF-16.

Code sample available in github from my Tridion Standard Templates share.

1
  • I reviced source code, but same error occured. XSLT1 is no problem, but XSLT2 cause the error.XSLT2 is get XML that is pushed by XSLT1 to package. Is this operation possible? I add reviced source code. Apr 10 '15 at 10:31
2

I think the error is because the XML declaration claims that the encoding is UTF-16, but the actual encoding is not. XslCompiledTransform(which is used internally) has a tendency to put such an UTF-16 XML declaration in the output and ignore the encoding specified in the xsl:output element.

Can you try what happens if you put omit-xml-declaration="true" on the xsl:output element of XSLT1 (that should suppress the XML declaration altogether and the default XML encoding is UTF-8).

2
  • I added omit-xml-declaration="yes" to XSLT1, then XML Declaration disappered, and no error occured. And XSLT2 is applied to the XML, so I can achieve my purpose by this way. Apr 20 '15 at 9:19
  • This helped me too! I had the same issue and adding omit-xml-declaration=yes to the first XSLT TBB it fixed the error. I would mark this as the answer to this question. Mar 10 '17 at 2:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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