I have some XML that represents two alternative versions of some text and I am using XSLT to perform the modification that selects one or other versions. In addition, one alternative also contains a placeholder that should be replaced with some other bit of text.

The XSLT is generated programmatically and is essentially an identity transformation with a couple of extra templates that perform the necessary tweaks. However, when the XSLT matches the alternative with the placeholder, the placeholder template doesn't get applied and is never filled in.

The actual code uses python's lxml, but I have been mostly testing the XSLT in notepad++ with the XML plugin. The plugin uses libxml2 and libxslt, like lxml, so they shouldn't be any different.

I have tried adding various versions of `<xsl:apply-template />` into template 2, but nothing results in the placeholder getting the value that I expect

The following is a very cut down version of the XML:

```xml
<sn:text xmlns:sn="http://some.namespace" xmlns="http://www.w3.org/1999/xhtml">
  <p>
    <sn:alts sn:id="alts_1">
      <sn:alt sn:id="alt_1">start 1</sn:alt>
      <sn:alt sn:id="alt_2">
        <sn:placeholder sn:id="p_1"/> start 2</sn:alt>
    </sn:alts> blah blah blah...</p>
</sn:text>

```

And the following is the generated XSLT:

```xml
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:sn="http://some.namespace">
  <!--template 1-->
  <xsl:template match="sn:placeholder[@sn:id='p_1']">XYZ</xsl:template>
  <!--template 2-->
  <xsl:template match="sn:alts[@sn:id='alts_1']">
    <xsl:value-of select="sn:alt[@sn:id='alt_2']" />
  </xsl:template>
  <!--identity transform-->
  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*|text()|comment()|processing-instruction">
    <xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>

```

The result that I am expecting should be something like:

```xml
<sn:text xmlns:sn="http://some.namespace" xmlns="http://www.w3.org/1999/xhtml">
  <p>XYZ start 2 blah blah blah...</p>
</sn:text>

```

Instead, the placeholder is not replaced with "XYZ", but is left out completely:

```xml
<sn:text xmlns:sn="http://some.namespace" xmlns="http://www.w3.org/1999/xhtml">
  <p> start 2 blah blah blah...</p>
</sn:text>

```

**Update**

Thanks for the pointers. It was quite obvious in the end:

```xml
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:sn="http://some.namespace">
  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" />
  <!--template 1-->
  <xsl:template match="sn:placeholder[@sn:id='p_1']">XYZ</xsl:template>
  <!--template 2-->
  <xsl:template match="sn:alts[@sn:id='alts_1']">
    <xsl:apply-templates select="sn:alt/sn:placeholder"/>
    <xsl:value-of select="sn:alt[@sn:id='alt_1']" />
  </xsl:template>
  <!--identity transform-->
  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*|text()|comment()|processing-instruction()">
    <xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>

```