模板的滚动总和导致XSL1.0

时间:2014-04-14 17:51:35

标签: templates xslt call xslt-1.0

我已经远远地搜索了一个这样的例子,到目前为止,我没有运用总和模板来使我的XSTL工作。

这是XML(每个计划特征的行数不同)

<PlanFeatures> 
 <PlanFeature name="Line0001">
  <CoordGeom>
   <Line>
    <Start pntRef="7540">5605 8950 1020</Start>
    <End pntRef="7541">5605 8951 1019</End>
   </Line>
   <Line>
    <Start pntRef="7541">5605 8951 1019</Start>
    <End pntRef="7542">5605 8947 1019</End>
   </Line>
   <Line>
    <Start pntRef="7542">5605 8947 1019</Start>
    <End pntRef="7543">5605 8940 1011</End>
   </Line>
   <Line>
    <Start pntRef="7543">5605 8940 1011</Start>
    <End pntRef="7544">5605 8931 1020</End>
   </Line>  
  </CoordGeom>
 </PlanFeature>
</PlanFeatures> 

这就是我使用XSL的地方,它使用递归调用模板来计算每个线段的距离。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:landxml="http://www.landxml.org/schema/LandXML-1.2" xmlns:hexagon="http://xml.hexagon.com/schema/HeXML-1.5" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-16" indent="no" omit-xml-declaration="yes"/>

<xsl:variable name="XML" select="/"/>
<xsl:variable name="fileExt" select="'txt'"/>
<xsl:variable name="fileDesc" select="'line distance report'"/>

<xsl:template match="/">  

<xsl:for-each select="$XML">
    <xsl:for-each select="landxml:LandXML/landxml:PlanFeatures/landxml:PlanFeature">
        <xsl:value-of select="@name"/><xsl:text>::</xsl:text>
        <xsl:for-each select="landxml:CoordGeom/landxml:Line">
            <xsl:value-of select="landxml:Start/@pntRef"/><xsl:text>-</xsl:text>
            <xsl:variable name="lista" select="landxml:Start"/>         
            <xsl:variable name="x1" select="substring-before($lista,' ')"/>
            <xsl:variable name="yt1" select="substring-after($lista,' ')"/>
            <xsl:variable name="y1" select="substring-before($yt1,' ')"/>
            <xsl:variable name="z1" select="substring-after($yt1,' ')"/>    
            <xsl:variable name="listb" select="landxml:End"/>
            <xsl:value-of select="landxml:End/@pntRef"/><xsl:text>: </xsl:text>
            <xsl:variable name="x2" select="substring-before($listb,' ')"/>
            <xsl:variable name="yt2" select="substring-after($listb,' ')"/>
            <xsl:variable name="y2" select="substring-before($yt2,' ')"/>
            <xsl:variable name="z2" select="substring-after($yt2,' ')"/>
            <xsl:variable name="seg" select= "((($x2 - $x1)*($x2 - $x1))+(($y2 - $y1)*($y2 - $y1))+(($z2 - $z1)*($z2 - $z1)))"/>

            <xsl:call-template name="root">
               <xsl:with-param name="X" select="$seg"/>
            </xsl:call-template> 
            <xsl:text>, </xsl:text>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="root"> 
        <xsl:param name="X"/> 
        <xsl:param name="xn" select="0"/> 
        <xsl:param name="xn_1" select="($X+1) div 2"/>       
        <xsl:choose> 
                <xsl:when test="string(number($X)) = 'NaN'"> 
                        <xsl:value-of select=" ' ' "/> 
                </xsl:when> 
                <xsl:when test="($xn_1 - $xn) * ($xn_1 - $xn) &lt; 0.00000001"> 
                        <xsl:value-of select='format-number($xn_1, "#.000")'/>          
                </xsl:when> 
                <xsl:otherwise> 
                        <xsl:call-template name="root"> 
                                <xsl:with-param name="X" select="$X"/> 
                                <xsl:with-param name="xn" select="$xn_1"/> 
                                <xsl:with-param name="xn_1" select="($xn_1 + ($X div $xn_1)) div 2"/> 
                        </xsl:call-template> 
                </xsl:otherwise> 
        </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet>

我需要从根调用模板中求和X(距离)的值,以创建一个表示每个线段总和的值。我想我需要使用一个匹配模板,但到目前为止,它甚至已经接近工作了。

目前正在导出LINEID :: StartPt-EndPt:dist,StartPt-EndPt:dist等。我还需要在每行末尾显示'dist'的总和。如下

Line0001::7540-7541: 1.414, 7541-7542: 2.000, 7542-7543: 12.042, 7543-7544: 12.720

但我想

Line0001::7540-7541: 1.414, 7541-7542: 2.000, 7542-7543: 12.042, 7543-7544: 12.728 -- 28.184

任何帮助都会受到赞赏......这个网站上的例子已经帮助了我很多,但我似乎无法克服这个障碍。

干杯,

克里斯

1 个答案:

答案 0 :(得分:0)

您可以通过一些相对简单的递归和参数传递来完成此操作。尝试用这四个模板替换您的第一个模板:

  <xsl:template match="/">
    <xsl:for-each select="$XML">
      <xsl:apply-templates 
           select="landxml:LandXML/landxml:PlanFeatures/landxml:PlanFeature" />
    </xsl:for-each>
  </xsl:template>

  <xsl:template match ="landxml:PlanFeature">
    <xsl:value-of select="concat(@name, '::')" />
    <xsl:apply-templates select="landxml:CoordGeom/landxml:Line[1]" />
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="landxml:Line">
    <xsl:param name="total" select="0" />

    <xsl:value-of 
         select="concat(landxml:Start/@pntRef, '-', landxml:End/@pntRef, ': ')"/>

    <xsl:variable name="len">
      <xsl:call-template name="root">
        <xsl:with-param name="X">
          <xsl:call-template name="seg" />
        </xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$len"/>

    <xsl:variable name="next" select="following-sibling::landxml:Line[1]" />
    <xsl:variable name="newTot" select="$total + $len" />
    <xsl:choose>
      <xsl:when test="$next">
        <xsl:text>, </xsl:text>
        <xsl:apply-templates select="$next">
          <xsl:with-param name="total" select="$newTot" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat(' -- ', format-number($newTot, '#.000'))" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="seg">
    <xsl:variable name="lista" select="landxml:Start"/>
    <xsl:variable name="x1" select="substring-before($lista,' ')"/>
    <xsl:variable name="yt1" select="substring-after($lista,' ')"/>
    <xsl:variable name="y1" select="substring-before($yt1,' ')"/>
    <xsl:variable name="z1" select="substring-after($yt1,' ')"/>
    <xsl:variable name="listb" select="landxml:End"/>
    <xsl:variable name="x2" select="substring-before($listb,' ')"/>
    <xsl:variable name="yt2" select="substring-after($listb,' ')"/>
    <xsl:variable name="y2" select="substring-before($yt2,' ')"/>
    <xsl:variable name="z2" select="substring-after($yt2,' ')"/>

    <xsl:value-of select= "($x2 - $x1)*($x2 - $x1)+
                           ($y2 - $y1)*($y2 - $y1)+
                           ($z2 - $z1)*($z2 - $z1)"/>
  </xsl:template>

在样本输入上运行时(在调整它以匹配XSLT中的路径之后),结果是:

Line0001::7540-7541: 1.414, 7541-7542: 4.000, 7542-7543: 10.630, 7543-7544: 12.728 -- 28.772