2014-02-27 73 views
0

我有一些令人不安的问题,正在总结与每个元素有关的arraySize属性数字。XSLT:以前所有属性的总和

XML代码:

<head> 
    <element> 
     <message name="something"> 
      <field arraySize="1"/> 
      <struct name="asdf"> 
       <struct name="qwera"> 
        <field arraySize="1"/> 
        <field arraySize="1"/>     
       </struct> 
       <struct name="xcv"> 
        <field arraySize="3"/> 
        <field arraySize="1"/> 
       </struct> 
       <struct name="nnge"> 
        <struct name="sdfssk"> 
         <field arraySize="1"/> 
         <field arraySize="1"/>     
        </struct> 
        <struct name="fhjmn"> 
         <field arraySize="2"/> 
         <field arraySize="1"/> 
        </struct> 
        <struct name="wetryk"> 
         <field arraySize="1"/> 
         <field arraySize="1"/> 
        </struct> 
       </struct> 
      </struct> 
      <field arraySize="1"/> 
     </message> 
    </element> 
    <element> 
     ... similar struct "tree" 
    </element> 
    <element> 
     ... similar struct "tree" 
    </element> 
</head> 

XSLT代码:这是怎么了,我试图解决这个问题。

<xsl:template match="p:struct"> 
    <xsl:apply-templates> 
     <xsl:with-param name="previous" select="sum(preceding-sibling::*//@arraySize)"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="p:field"> 
    <xsl:param name="previous" select="0"/> 
    <xsl:value-of select="$previous + sum(preceding-sibling::*//@arraySize)"/> 
</xsl:template> 

预期输出:

element #1 
1 
2 
3 
6 
7 
8 
9 
11 
12 
13 
14 
15 

element #2 
1 
2 
... etc 

实际输出:

1 <-- Problem #1 
1 
2 
5 
6 
1 <--- Problem #2 
2 
4 
5 
6 
7 
15 <-- The correct summation is produced here. 

我需要总结的所有preseding ARRAYSIZE的属性。它有点作用,但是两个问题是:1.第一个领域没有总结。 2.总和重新开始于第三个缩进结构(如果缩进是正确的术语)。

有人可以帮助我吗?

+0

你能告诉你真正希望在这个输出案件?谢谢! –

+0

哦,对不起。忘了那个。我编辑了这篇文章。 –

回答

0

对此,我认为您应该使用preceding::轴而不是preceding-sibling::轴。

像这样:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:p="aaa"> 
    <xsl:output method="text" indent="yes"/> 

    <xsl:variable name="nl" select="'&#xA;'" /> 

    <xsl:template match="text()" /> 

    <xsl:template match="/*"> 
    <xsl:apply-templates select="p:element" /> 
    </xsl:template> 

    <xsl:template match="p:element"> 
    <xsl:value-of select="concat('element #', position(), $nl)"/> 
    <xsl:apply-templates /> 
    <xsl:value-of select="$nl"/> 
    </xsl:template> 

    <xsl:template match="p:field"> 
    <xsl:variable name="elId" select="generate-id(ancestor::p:element)" /> 
    <xsl:variable name="preds" 
        select="preceding::*/@arraySize[generate-id(ancestor::p:element) = 
                $elId]" /> 
    <xsl:value-of select="concat(@arraySize + sum($preds), $nl)"/> 
    </xsl:template> 
</xsl:stylesheet> 

产生输出:

element #1 
1 
2 
3 
6 
7 
8 
9 
11 
12 
13 
14 
15 

element #2 
1 
2 
3 
+0

谢谢您的回复,但我只注意到我忽略了一些细节而犯了相当大的错误。有多个元素节点,它只应该总结其内部的属性。我很抱歉,并希望你仍然可以提供一些帮助。 –

+0

@ user3010546但是现在你的XML源缺少一个根元素,所以它是无效的。 –

+0

对不起。根添加。 –

0

这里的另一种方式,你可以看看它:

<xsl:template match="/"> 
<xsl:for-each select="head/element"> 
    <xsl:variable name="elementID" select="generate-id()" /> 
    <xsl:value-of select="concat('element #', position(), '&#10;')"/> 
    <xsl:for-each select=".//field"> 
     <xsl:value-of select="@arraySize + sum(preceding::field[generate-id(ancestor::element)=$elementID]/@arraySize)" /> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 
</xsl:for-each> 
</xsl:template>