【问题标题】:Counting same values in xml using XSLT使用 XSLT 在 xml 中计算相同的值
【发布时间】:2012-12-24 06:30:50
【问题描述】:

我想在输出中添加<LineNum>[number]</LineNum>,如果<cell num="4"> 中有不同的值,LineNum 必须再次从“1”开始

源xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<table>
   <sheet name="Notification" num="1">
      <row num="1">
         <cell num="1">IBD</cell>
         <cell num="2">YES</cell>
         <cell num="3">6600027830(010000)</cell>
         <cell num="4">800015001</cell>
      </row>
      <row num="2">
         <cell num="1">IBD</cell>
         <cell num="2">YES</cell>
         <cell num="3">6600027830(010000)</cell>
         <cell num="4">800015001</cell>
      </row>
      <row num="3">
         <cell num="1">IBD</cell>
         <cell num="2">YES</cell>
         <cell num="3">6600027831(010000)</cell>
         <cell num="4">800015002</cell>
      </row>
      <row num="4">
         <cell num="1">IBD</cell>
         <cell num="2">YES</cell>
         <cell num="3">6600027831(010000)</cell>
         <cell num="4">800015002</cell>
      </row>
      <row num="5">
         <cell num="1">IBD</cell>
         <cell num="2">YES</cell>
         <cell num="3">6600027831(010000)</cell>
         <cell num="4">800015002</cell>
      </row>
   </sheet>
</table>

在这种情况下也是如此:

<cell num="4">800015001</cell>
<LineNum>1</LineNum>
<cell num="4">800015001</cell>
<LineNum>2</LineNum>

<!-- cell num="4" different from previous, start LineNum from 1 -->
<cell num="4">800015002</cell>
<LineNum>1</LineNum>
<cell num="4">800015002</cell>
<LineNum>2</LineNum>
<cell num="4">800015002</cell>
<LineNum>3</LineNum>

我可以添加全局变量,将单元格 num="4" 分配给它,然后检查当前值是否与全局变量相同,如果不是 - 再次从 1 开始 LineNum 并重新分配全局变量。遗憾的是 XSLT 不提供重新分配。

我能做什么?

统一更新: 试图以某种方式修改来自其他问题XSL: Counting Previous Unique Siblings 的示例,但没有运气..

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

  <xsl:output method="text"/>

  <!-- don't copy whitespace -->
  <xsl:template match="text()"/>

  <xsl:template match="row/cell[@num=4]">
    <xsl:variable name="roles-so-far" select=". | preceding::row/cell[@num=4]"/>
    <xsl:value-of select="count($roles-so-far)"/>
    <xsl:value-of select="' '"/>
    <xsl:value-of select="."/>

    <!-- Only select the first instance of each ROLE name -->
    <xsl:variable name="roles-so-far-unique"
                  select="$roles-so-far[not(. = preceding-sibling::row/cell[@num=4])]"/>

    <xsl:apply-templates select="/"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="count($roles-so-far-unique)"/>
    <xsl:text>&#xA;</xsl:text> <!-- linefeed -->


  </xsl:template>

</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt xpath xslt-2.0


    【解决方案1】:

    问题被标记为 xslt-2.0,您可以轻松使用for-each-group group-adjacent:

    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      exclude-result-prefixes="xs"
      version="2.0">
    
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="@* | node()">
      <xsl:copy>
        <xsl:apply-templates select="@* , node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="sheet">
      <xsl:copy>
        <xsl:for-each-group select="row" group-adjacent="cell[@num = 4]">
          <xsl:apply-templates select="current-group()"/>
        </xsl:for-each-group>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="row">
      <xsl:copy>
        <xsl:apply-templates select="@* , node()"/>
        <LineNum><xsl:value-of select="position()"/></LineNum>
      </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    当我将 Saxon 9.4 的上述代码应用于您的输入样本时,我得到以下结果:

    <table>
       <sheet>
          <row num="1">
             <cell num="1">IBD</cell>
             <cell num="2">YES</cell>
             <cell num="3">6600027830(010000)</cell>
             <cell num="4">800015001</cell>
             <LineNum>1</LineNum>
          </row>
          <row num="2">
             <cell num="1">IBD</cell>
             <cell num="2">YES</cell>
             <cell num="3">6600027830(010000)</cell>
             <cell num="4">800015001</cell>
             <LineNum>2</LineNum>
          </row>
          <row num="3">
             <cell num="1">IBD</cell>
             <cell num="2">YES</cell>
             <cell num="3">6600027831(010000)</cell>
             <cell num="4">800015002</cell>
             <LineNum>1</LineNum>
          </row>
          <row num="4">
             <cell num="1">IBD</cell>
             <cell num="2">YES</cell>
             <cell num="3">6600027831(010000)</cell>
             <cell num="4">800015002</cell>
             <LineNum>2</LineNum>
          </row>
          <row num="5">
             <cell num="1">IBD</cell>
             <cell num="2">YES</cell>
             <cell num="3">6600027831(010000)</cell>
             <cell num="4">800015002</cell>
             <LineNum>3</LineNum>
          </row>
       </sheet>
    </table>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多