第一个元素

时间:2012-10-29 01:33:33

标签: xml xslt

XSLT XML问题。

寻找一个简单的转变。我有简单的索引xml输入。我必须为每一章输出第一个和最后一个元素。如下所示。任何帮助将不胜感激。

关心JJ

输入

<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>

输出

<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>

1 个答案:

答案 0 :(得分:3)

更新以利用更清晰的谓词 - 感谢@ SeanB.Durkin。

<强>予。 XSLT 1.0解决方案

当这个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>

...适用于原始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>

...产生了所需的结果:

<?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>

<强>解释

  • 请注意正确使用Muenchian Grouping按其值确定唯一的<page>元素。
  • 对于每个唯一的<page>元素,将复制两个<page>元素:包含唯一值的组中的第一个和最后一个元素。

<强> II。 XSLT 2.0解决方案

请注意,在XSLT 2.0中,解决方案变得更加简单。

当这个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>

...应用于原始XML,生成相同的所需结果:

<?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>

<强>解释

  • 应用了相同的方法,但使用的是XSLT 2.0的for-each-group元素和current-group()指令,而不是Muenchian Grouping。