Adding an attribute after an element with apply-templates behaves differently with xalan-c and xsltproc. What is correct?

StackOverflow https://stackoverflow.com/questions/14375316

  •  16-01-2022
  •  | 
  •  

Question

I am noticing the following difference between xalan-c and xsltproc. Which one of these is correct? What does the spec say about this?

Source xml :-

<a attr="val1">
  <b d="5">
  </b>
  <b d="10">
  </b>
</a>

Stylesheet :-

<xsl:template match="@* | text() | comment() | processing-instruction()">
  <xsl:copy/>
</xsl:template>

<xsl:template match="*">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="a">
  <a>
    <c>
      <xsl:call-template name="gcd">
        <xsl:with-param name="nums" select="./b/@d"/>
      </xsl:call-template>
    </c>
    <xsl:apply-templates select="./@*"/>
  <a>
</xsl:template>

xsltproc gives me :-

<a attr="val1">
  <c>5</c>
</a>

While xalan-c gives me :-

<a>
  <c>5</c>
</a>
Was it helpful?

Solution

I think the issue could be around this line here

<xsl:apply-templates select="./@*"/>

In particular, its position, which is after you have created the c element in the template. Attributes should be added on to an element before any child elements. Indeed, I am surprised you are not getting an error along the lines of "Attribute nodes must be added before any child nodes to an element."

Assuming you do want the attribute added to the a element, try the following

<xsl:template match="a">
  <a>
    <xsl:apply-templates select="@*"/>
    <c>
      <xsl:call-template name="gcd">
        <xsl:with-param name="nums" select="./b/@d"/>
      </xsl:call-template>
    </c>
  <a>
</xsl:template>

This should then give consistent results.

And if you don't want the attributes, simply remove the apply-templates

OTHER TIPS

The xsltproc behaviour seems incorrect to me. As Tim C says, the spec gives two options: ignoring the attribute or signalling an error. It does not allow the option of actually adding the attribute to the element in its proper place. However, for these cases where the spec defines a "recoverable error", getting the wrong recovery action for the error isn't really that serious a non-conformance, especially when the recovery action is to do what the user probably intended. Fact is, the stylesheet is in error and should be fixed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top