first last element

后端 未结 1 833
不思量自难忘°
不思量自难忘° 2021-01-21 12:23

XSLT XML Question.

Looking into a simple transformation. I have simple index xml input. I have to output the the first and last element with a for each chapter. AS shown

相关标签:
1条回答
  • 2021-01-21 12:44

    Updated to take advantage of a cleaner predicate - thanks to @SeanB.Durkin.

    I. XSLT 1.0 Solution

    When this XSLT:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
      <xsl:output omit-xml-declaration="no" indent="yes" />
      <xsl:strip-space elements="*" />
    
      <xsl:key name="kChapters" match="page" use="." />
    
      <xsl:template match="/*">
        <book>
          <xsl:apply-templates 
            select="page[generate-id() = generate-id(key('kChapters', .)[1])]" />
        </book>
      </xsl:template>
    
      <xsl:template match="page">
        <xsl:copy-of select=".|key('kChapters', .)[last()]" />
      </xsl:template>
    
    </xsl:stylesheet>
    

    ...is applied to the original XML:

    <book>
      <page number="1">Chapter01</page>
      <page number="2">Chapter01</page>
      <page number="3">Chapter01</page>
      <page number="4">Chapter01</page>
      <page number="5">Chapter01</page>
      <page number="6">Chapter01</page>
      <page number="7">Chapter02</page>
      <page number="8">Chapter02</page>
      <page number="9">Chapter02</page>
      <page number="10">Chapter02</page>
      <page number="11">Chapter02</page>
      <page number="12">Chapter02</page>
      <page number="13">Chapter03</page>
      <page number="14">Chapter03</page>
      <page number="15">Chapter03</page>
      <page number="16">Chapter03</page>
      <page number="17">Chapter03</page>
      <page number="18">Chapter03</page>
    </book>
    

    ...the desired result is produced:

    <?xml version="1.0"?>
    <book>
      <page number="1">Chapter01</page>
      <page number="6">Chapter01</page>
      <page number="7">Chapter02</page>
      <page number="12">Chapter02</page>
      <page number="13">Chapter03</page>
      <page number="18">Chapter03</page>
    </book>
    

    Explanation:

    • Note the proper use of Muenchian Grouping to determine the unique <page> elements by their value.
    • For each unique <page> element, two <page> elements are copied: the first and last from the group that contains the unique value.

    II. XSLT 2.0 Solution

    Note that in XSLT 2.0, the solution becomes even simpler.

    When this XSLT:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
      <xsl:output omit-xml-declaration="no" indent="yes" />
      <xsl:strip-space elements="*" />
    
      <xsl:template match="/*">
        <book>
          <xsl:for-each-group select="page" group-by=".">
            <xsl:copy-of select=".|current-group()[last()]" />
          </xsl:for-each-group>
        </book>
      </xsl:template>
    
    </xsl:stylesheet>
    

    ...is applied to the original XML, the same desired result is produced:

    <?xml version="1.0"?>
    <book>
      <page number="1">Chapter01</page>
      <page number="6">Chapter01</page>
      <page number="7">Chapter02</page>
      <page number="12">Chapter02</page>
      <page number="13">Chapter03</page>
      <page number="18">Chapter03</page>
    </book>
    

    Explanation:

    • The same methodology is applied, but instead of Muenchian Grouping, XSLT 2.0's for-each-group element and current-group() instruction are used.
    0 讨论(0)
提交回复
热议问题