2
votes

Hi I have following xml,

<doc>
 <footnote>
   <p type="Footnote Text">
       <link ref="http://www.facebook.org"/>
   </p>
 </footnote>
<footnote>
   <p type="Footnote Text">
       <link ref="http://www.wiki.org"/>
   </p>
 </footnote>
<footnote>
   <p type="Footnote Paragraph">
       <link ref="http://www.wiki.org"/>
   </p>
 </footnote>
</doc>

what I need to do is add new attribute (id='number-1') to <p> nodes where its attribute type is eqal to Footnote Text. in this case only first two <p> nodes should apply the new <id> attribute.

so I wrote following code,

<xsl:template match="p/@type[.='Footnote Text']">
   <xsl:copy>
      <xsl:attribute name="id">
         <xsl:value-of select="'number-'"/><xsl:number level="any"/>
      </xsl:attribute>
      <xsl:apply-templates select="node()|@*"/>
   </xsl:copy>
</xsl:template>

but it does not add the new attribute to <p> node. however when I remove the @type[.='Footnote Text'] it adds the new node to all <p> nodes as expected.

my intended output is follows

<doc>
   <footnote>
      <p type="Footnote Text" id="number-1">
          <link ref="http://www.facebook.org"/>
      </p>
   </footnote>
   <footnote>
     <p type="Footnote Text" id="number-2>
        <link ref="http://www.wiki.org"/>
     </p>
   </footnote>
   <footnote>
     <p type="Footnote Paragraph">
       <link ref="http://www.wiki.org"/>
     </p>
   </footnote>
 </doc>

How can I filter the <p> nodes that have type="Footnote Text" attribute and add new attribute to those <p> nodes ?

1

1 Answers

3
votes

You need to add the attribute to the element:

<xsl:template match="p[@type = 'Footnote Text']">
   <xsl:copy>
      <xsl:attribute name="id">
         <xsl:value-of select="'number-'"/><xsl:number count="p[@type = 'Footnote Text']" level="any"/>
      </xsl:attribute>
      <xsl:apply-templates select="node()|@*"/>
   </xsl:copy>
</xsl:template>