.net – xsl:template match doesn’t find matches

.netxmlxslt

I'm trying to convert some Xaml to HTML using the .NET XslCompiledTransform and am running into difficulties getting the xslt to match Xaml tags. For instance with this Xaml input:

<FlowDocument PagePadding="5,0,5,0" AllowDrop="True" NumberSubstitution.CultureSource="User" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Paragraph>a</Paragraph>
</FlowDocument>

And this xslt:

<?xml version="1.0" encoding="utf-8"?>
<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"
>

  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="FlowDocument">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="Paragraph" >
    <p>
      <xsl:apply-templates />
    </p>
  </xsl:template>

I get this output:

<html>
    <body>
  a
</body>
</html>

Rather than the expected:

<html>
   <body>
      <p>a</p>
   </body>
</html>

Could this be a problem with the namespace? This is my first attempt at an xsl transform, so I'm at a loss.

Best Solution

Yes, it's a problem with the namespace. All of the elements in your input document are in the namespace http://schemas.microsoft.com/winfx/2006/xaml/presentation. Your template is trying to match elements that are in the default namespace, and it's not finding any.

You need to declare this namespace in your transform, assign it a prefix, and then use that prefix in any patterns that are intended to match elements in that namespace. So your XSLT should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    exclude-result-prefixes="msxsl"/>

<xsl:output method="html" indent="yes"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates />
    </body>
  </html>
</xsl:template>

<xsl:template match="p:FlowDocument">
  <xsl:apply-templates />
</xsl:template>

<xsl:template match="p:Paragraph" >
  <p>
    <xsl:apply-templates />
  </p>
</xsl:template>
Related Question