Search code examples
xmlxslt

Why does using the mode attribute in my XSLT just make it print the whole XML?


Working on a larger transform, but was able to replicate this in a mock-up. If I use the "mode" attribute in my XSLT template, the result is just the raw text (without markup) of the original XML that is supposed to be transformed. If I instead use the "name" attribute, it transforms as expected.

XML

<Parent>
 <ParentCon>Parent Content</ParentCon>
 <Child>
  <ChildCon>Child Content</ChildCon>
  <Grandchild>Some Grandchild Content</Grandchild>
 </Child>
</Parent>

XSLT (with mode attribute)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Parent" mode="xyz">

    <ExportParent>
       <ExportChild>
      </ExportChild>
    </ExportParent>

  </xsl:template>

</xsl:stylesheet>

Output (with mode attribute)

<?xml version="1.0" encoding="UTF-8"?>
 Parent Content
 
  Child Content
  Some Grandchild Content

XSLT (with name attribute)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Parent" name="xyz">

    <ExportParent>
       <ExportChild>
      </ExportChild>
    </ExportParent>

  </xsl:template>

</xsl:stylesheet>

Output (with name attribute)

<?xml version="1.0" encoding="UTF-8"?><ExportParent><ExportChild/></ExportParent>

Googling suggests that name and mode are functionally the same, except mode allows for re-use.

I expected the output to be the same with both attributes.


Solution

  • The problem with your template with mode attribute is that it is never applied, and the entire transformation is performed using only the built-in template rules.

    The XSLT 1.0 specification states that:

    if an xsl:apply-templates element does not have a mode attribute, then it applies only to those template rules from xsl:template elements that do not have a mode attribute.

    There is no xsl:apply-templates instruction in your XSLT, and the built-in template rule applies templates without mode.

    The result of processing an XML using only the built-in template rules is a copy of all the text nodes in the input document.

    The name of a template plays no role unless you are calling the template by its name.

    See:
    https://www.w3.org/TR/1999/REC-xslt-19991116/#modes
    https://www.w3.org/TR/1999/REC-xslt-19991116/#built-in-rule
    https://www.w3.org/TR/1999/REC-xslt-19991116/#named-templates