我真的希望我的标题至少清楚一点。
重要:我只能使用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)
最好使用键获取"相关"数据。把它放在样式表的顶部,在任何模板之外:
<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>: Wall area: </xsl:text>
<xsl:value-of select="format-number(sum(key('wall', key('wallSegment', WallSegments/WallSegment/@id)/@wall)/@innerArea), '0.00m²')"/>
<xsl:text> </xsl:text>
</paragraph>
</xsl:for-each>
将返回:
<paragraph>Room 1:
Wall area: 51.09m²</paragraph>
如果你需要的是每个房间的面积,这是一个得到它的方法:
<?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