开发者

XSLT - How to select top a to top b

开发者 https://www.devze.com 2023-03-15 09:22 出处:网络
how can I extract the first 2 C-Values (\'Baby\' and \'Cola\') where B is \'RED\'. Input instance is:

how can I extract the first 2 C-Values ('Baby' and 'Cola') where B is 'RED'. Input instance is:

<Root>
  <A>
    <B>BLACK</B>
    <C>Apple</C>
  &l开发者_JS百科t;/A>
  <A>
    <B>RED</B>
    <C>Baby</C>
  </A>
  <A>
    <B>GREEN</B>
    <C>Sun</C>
  </A>
  <A>
    <B>RED</B>
    <C>Cola</C>
  </A>
  <A>
    <B>RED</B>
    <C>Mobile</C>
  </A>
</Root>

Output instance must be:

<Root>
  <D>Baby</D>
  <D>Cola</D>
</Root>

I thought about the combination of for-each and global variables. But in XSLT it is not possible to change the value for a global variable to break the for-each. I have no idea anymore.


No need for breaking the for-each:

<xsl:template match="Root">
  <xsl:copy>
    <xsl:for-each select="(A[B='RED']/C)[position() &lt; 3]">
      <D><xsl:value-of select="." /></D>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>


This is very elegantly solved with an xsl:key.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:key name="kB" match="A" use="B" />

  <xsl:template match="Root">
    <xsl:copy>
      <xsl:apply-templates select="key('kB', 'RED')[position() &lt; 3]" />
    </xsl:copy>     
  </xsl:template>

  <xsl:template match="A">
    <D><xsl:value-of select="C" /></D>
  </xsl:template>

</xsl:stylesheet>

gives, with your input

<Root>
  <D>Baby</D>
  <D>Cola</D>
</Root>


No need iteration, just apply the templates to the required elements:

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="Root">
        <Root>
            <xsl:apply-templates select="A/B[
                .='RED' 
                and 
                count(../preceding-sibling::A[B='RED'])&lt;2]"/>
        </Root>     
    </xsl:template>


    <xsl:template match="B">
        <D>
            <xsl:value-of select="following-sibling::C"/>
        </D>
    </xsl:template>

</xsl:stylesheet>

When applied on your input gives:

<Root>
   <D>Baby</D>
   <D>Cola</D>
</Root>
0

精彩评论

暂无评论...
验证码 换一张
取 消