我需要输出具有正确序列号的outbuilding节点(仅限且只有具有'vacant'子节点的节点)(参见XML)
下面的XML中没有属性,只有元素和值。
<stuff>
<locations>
<location>
<properties>
<property>
<belongings>
<house>
<houseWithAC/>
</house>
</belongings>
</property>
<property>
<belongings>
<outbuilding/>
</belongings>
</property>
<property>
<belongings>
<outbuilding>
<vacant/>
</outbuilding>
</belongings>
</property>
<property>
<belongings>
<outbuilding>
<vacant/>
</outbuilding>
</belongings>
</property>
<property>
<belongings>
<vehicle/>
</belongings>
</property>
</properties>
</location>
<location>
<properties>
<property>
<belongings>
<vehicle/>
</belongings>
</property>
<property>
<belongings>
<outbuilding/>
</belongings>
</property>
<property>
<belongings>
<house/>
</belongings>
</property>
<property>
<belongings>
<outbuilding>
<vacant/>
</outbuilding>
</belongings>
</property>
<property>
<belongings>
<barn/>
</belongings>
</property>
</properties>
</location>
</locations>
</stuff>
排序:我需要计算每个位置的每个所属子节点(例如房屋,附属建筑,车辆)注意,带有houseWithAC子房的房子计为两个节点!! 序列格式为Loc ### / Item ###
我需要输出每个具有空缺孩子的附属建筑节点,并使用正确的序列号(见上文)
另请注意:“集合”节点(如位置,属性)有很多子节点,而节点所有物只有一个。
我试图创建一个递归循环,但是id不起作用:如果我有没有“空置”的外部节点 - 孩子我仍然会进入if语句(看起来这个条件总是如此)
这样的事情: 。 。 。 。 。 。 。 。 。 。
<xsl:for-each select="Locations/Location">
<xsl:variable name="LOCID">
<xsl:number level="single" count="*" format="001"/>
</xsl:variable>
<xsl:call-template name="WriteItems">
<xsl:with-param name="propertiesNodes" select="properties/property"/>
<xsl:with-param name="NumberOfProperties" select="count(properties/property)"/>
<xsl:with-param name="LocCount" select="$LOCID"/>
</xsl:call-template>
</xsl:for-each>
. . . . . . . . . . . . .
<xsl:template name="WriteItems">
<xsl:param name="propertiesNodes"/>
<xsl:param name="NumberOfProperties"/>
<xsl:param name="LocCount"/>
<xsl:param name="Index">1</xsl:param>
<xsl:param name="ItemCount">1</xsl:param>
<xsl:choose>
<xsl:when test="$Index > $NumberOfProperties"/>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$propertiesNodes[$Index]/belongings/house/houseWithAC">
<xsl:call-template name="WriteItems">
<xsl:with-param name="propertiesNodes" select="$propertiesNodes"/>
<xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/>
<xsl:with-param name="LocCount" select="$LocCount"/>
<xsl:with-param name="Index" select="$Index + 1"/>
<xsl:with-param name="ItemCount" select="$ItemCount + 2"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$propertiesNodes[$Index]/belongings/house">
<xsl:call-template name="WriteItems">
<xsl:with-param name="propertiesNodes" select="$propertiesNodes"/>
<xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/>
<xsl:with-param name="LocCount" select="$LocCount"/>
<xsl:with-param name="Index" select="$Index + 1"/>
<xsl:with-param name="ItemCount" select="$ItemCount + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$propertiesNodes[$Index]/belongings/vehicle">
<xsl:call-template name="WriteItems">
<xsl:with-param name="propertiesNodes" select="$propertiesNodes"/>
<xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/>
<xsl:with-param name="LocCount" select="$LocCount"/>
<xsl:with-param name="Index" select="$Index + 1"/>
<xsl:with-param name="ItemCount" select="$ItemCount + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$propertiesNodes[$Index]/belongings/barn">
<xsl:call-template name="WriteItems">
<xsl:with-param name="propertiesNodes" select="$propertiesNodes"/>
<xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/>
<xsl:with-param name="LocCount" select="$LocCount"/>
<xsl:with-param name="Index" select="$Index + 1"/>
<xsl:with-param name="ItemCount" select="$ItemCount + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$propertiesNodes[$Index]/belongings/outbuilding">
<xsl:if test="$propertiesNodes[$Index]/belongings/outbuilding/vacant">
<xsl:variable name="ITEMID">
<xsl:value-of select="format-number($ItemCount,'000')"/>
</xsl:variable>
.... output as concat('- ', $LocCount, '/', $ITEMID) ...... some description ....
</xsl:if>
<xsl:call-template name="WriteItems">
<xsl:with-param name="propertiesNodes" select="$propertiesNodes"/>
<xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/>
<xsl:with-param name="LocCount" select="$LocCount"/>
<xsl:with-param name="Index" select="$Index + 1"/>
<xsl:with-param name="ItemCount" select="$ItemCount + 1"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 0 :(得分:2)
我不确定我是否正确理解了您的问题,但如果这是您想要的:
对于每个空置“项目”,输出:
然后你可以通过循环遍历位置和“项目”并使用position()
函数来确定何时找到匹配来实现此目的。像这样:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//location">
<xsl:variable name="locposition" select="position()"/>
<xsl:for-each select=".//belongings//*[not(self::vacant)]">
<xsl:if test="vacant">
<xsl:value-of select="format-number($locposition, '000')"/>
<xsl:text> / </xsl:text>
<xsl:value-of select="format-number(position(), '000')"/>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
使用您的示例输入,将输出以下内容:
001 / 004
001 / 005
002 / 004
编辑添加:以下是使用xsl:number
的替代解决方案,可避免显式循环:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="*[vacant]">
<xsl:number count="location" format="001"/>
<xsl:text> / </xsl:text>
<xsl:number count="*[not(self::vacant)][ancestor::belongings]"
level="any" from="location" format="001"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>