如何在xslt 1.0中用xpath多次获取id引用的属性值的总和?

时间:2014-08-06 14:03:08

标签: xpath xslt-1.0

我真的希望我的头衔至少有点清楚。

重要:我只能使用xslt 1.0,因为项目需要使用MSXML XSLT处理器。

我尝试做什么: 我生成包含房间信息的文档。房间有墙,我需要每个房间的墙面积的总和。

我得到的输入xml文件是由另一个程序动态创建的。 更改输入xml文件的结构不是解决方案,相信我,它需要这样,并且比我在这里展示的要复杂得多。

我的XML(wall元素中的innerArea属性必须总结):

<root>
    <floor id="30" name="EG">
        <flat name="Wohnung" nr="1">
            <Room id="49" area="93.08565">
                <WallSegments>
                    <WallSegment id="45"/>
                    <WallSegment id="42"/>
                    <WallSegment id="39"/>
                </WallSegments>
            </Room>
        </flat>
    </floor>
    <components>
        <Wall id="20" innerArea="20.7654"/>
        <wallSegment id="45" wall="20">[...]</wallSegment>
        <Wall id="21" innerArea="12.45678"/>
        <wallSegment id="42" wall="21">[...]</wallSegment>
        <Wall id="22" innerArea="17.8643"/>
        <wallSegment id="39" wall="22">[...]</wallSegment>
    </components>
</root>

通过我的XSLT,我能够达到属于房间的墙壁的价值。 但我真的不知道如何从中得到价值的总和。

我的XSLT:

<xsl:for-each select="flat/Room">
    <xsl:for-each select="WallSegments/WallSegment">
        <xsl:variable name="curWallSegId" select="@id"/>
        <xsl:for-each select="/root/components/wallSegment[@id = $curWallSegId]">
            <xsl:variable name="curWallId" select="@wall"/>
            <xsl:for-each select="/root/components/Wall[@id = $curWallId]">
                <!--I didn't expect that this was working, but at least I tried :D-->
                <xsl:value-of select="sum(@AreaInner)"/> 
              </xsl:for-each>
            </xsl:for-each>
          </xsl:for-each>
        </xsl:for-each>

所需的输出应该是......

[...]
<paragraph>
    Room 1:
      Wall area: 51.09 m²
    [...]
</paragraph>
[...]

所以我希望我能正确描述我的问题。如果没有:我很抱歉,你可能会打败我的脸x)

2 个答案:

答案 0 :(得分:1)

最好使用来获取“相关”数据。将它放在样式表的顶部,在任何模板之外:

<xsl:key name="wall" match="components/Wall" use="@id" />
<xsl:key name="wallSegment" match="components/wallSegment" use="@id" />

然后:

<xsl:for-each select="flat/Room">
    <paragraph>
        <xsl:text>Room </xsl:text>
        <xsl:value-of select="position()"/>
        <xsl:text>:&#10;  Wall area: </xsl:text>
        <xsl:value-of select="format-number(sum(key('wall', key('wallSegment', WallSegments/WallSegment/@id)/@wall)/@innerArea), '0.00m²')"/>
        <xsl:text> &#10;</xsl:text>
    </paragraph>
</xsl:for-each>

将返回:

<paragraph>Room 1:
  Wall area: 51.09m²</paragraph>

答案 1 :(得分:0)

如果你需要的是每个房间的区域,这是获得它的一种方式:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="/root/floor">
        <xsl:for-each select="flat/Room">
            <xsl:variable name="currentRoomSegmentsIds" select="WallSegments/WallSegment/@id"/>
            <xsl:variable name="currentRoomWallsIds" select="/root/components/wallSegment[@id = $currentRoomSegmentsIds]/@wall"/>
            <xsl:variable name="currentRoomWallsInnerAreas" select="/root/components/Wall[@id = $currentRoomWallsIds]/@innerArea"/>
            Id of the room = <xsl:value-of select="@id"/>.
            Area of the room = <xsl:value-of select="sum($currentRoomWallsInnerAreas)"/>
        </xsl:for-each> <!-- Enf of for each room -->
    </xsl:template>
</xsl:stylesheet>

这会产生以下结果:

Id of the room = 49. Area of the room = 51.08648