xslt processing on select attribute on apply-templ

2019-02-21 03:52发布

问题:

I have a XSLT as below and apply this xslt into the input xml[pasted below], it is working fine except one thing that need to clarify.

this is the input xml

<Test>
  <Experiment id='1'>
    <Dish1>
      <Conditions pressure='x' temp='y'/>
      <Measurement timeStamp='8am' reading='y'/>
    </Dish1>
    <Dish2>
      <Conditions pressure='x' temp='y'/>
      <Measurement timeStamp='8am' reading='y'/>
    </Dish2>
    <Dish1>
      <Conditions pressure='x' temp='y'/>
      <Measurement timeStamp='2pm' reading='y'/>
    </Dish1>
    <Dish2>
      <Conditions pressure='x' temp='y'/>
      <Measurement timeStamp='2pm' reading='y'/>
    </Dish2>
   </Experiment>
   <Experiment id='2'>
    <Dish1>
      <Conditions pressure='x' temp='y'/>
      <Measurement timeStamp='9am' reading='y'/>
    </Dish1>
    </Experiment>
</Test>

this is the xslt

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="Experiment">
      <xsl:copy>
         <xsl:apply-templates select="@*" />
         <xsl:for-each-group select="*" group-by="local-name()">
            <xsl:copy>
               <xsl:apply-templates select="current-group()" />

            </xsl:copy>
         </xsl:for-each-group>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="Experiment/*">
      <Observation>
         <xsl:apply-templates select="*/@*" />
      </Observation>
   </xsl:template>

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

</xsl:stylesheet>

This is transformation is working fine. But, if i change as below on the xslt, then, it is getting error. Any idea?

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

I.e., On the last match, I have changed from <xsl:apply-templates select="@*|node()"/> to <xsl:apply-templates select="."/>

回答1:

. means the current node. When you apply-templates to ., you're applying them to the current context.

In your case, the template will match Test, output a copy of it, and apply-templates to itself. It will then match again basically putting you into an endless loop.

By doing the apply-templates on node()|@*, you're applying templates to all child nodes and attributes.



标签: xslt