我建立了带有地点的索引。输出应该从大到小,即
纽约,曼哈顿,华尔街
问题是,有时候街道不属于一个地区,而是属于两个地区,有时甚至根本没有地区,但街道被直接列在城市下。
因此,每当我获得idno并在这样的代码上使用它时:
<?xml version="1.0" encoding="UTF-8"?>
<listplaces>
<place>
<placeName type="city">City A</placeName>
<idno>CA</idno>
</place>
<place>
<placeName type="district">District B</placeName>
<idno>DB</idno>
<belongsTo active="CA" passive="DB"/>
</place>
<place>
<placeName type="district">District C</placeName>
<idno>DC</idno>
<belongsTo active="CA" passive="DC"/>
</place>
<place>
<placeName type="street">Street D</placeName>
<idno>SD</idno>
<belongsTo active="DB" passive="SD"/>
<belongsTo active="DC" passive="SD"/>
</place>
<place>
<placeName type="street">Street E</placeName>
<idno>SE</idno>
<belongsTo active="CA" passive="SE"/>
</place>
</listplaces>
这应该根据idno输出
idno CA: City A
idno DB: City A, District B
idno DC: City A, District C
idno SD: City A, District B, Street D
idno SD: City A, District C, Street D
idno SE: City A, Street E
问题是,当我处于最低级别时,以正确的顺序创建输出-跟随所有@active关系到顶部。我找到了一个解决方案,在该解决方案中,我始终在字符串的左侧连接活动的placeName。但是我不知道如何让XSLT处理所有可能的变体并相应地创建所需的字符串。
(我使用XSLT 3.0)
答案 0 :(得分:1)
我可能对逻辑有误解,但考虑使用按键通过belongTo
<xsl:key name="places" match="place" use="belongsTo/@active" />
您将从选择第一位开始($idno
是包含所需值的参数)
<xsl:apply-templates select="place[idno = $idno]" />
然后在与place
匹配的模板中进行输出,您将像这样处理其“子级”
<xsl:apply-templates select="key('places', idno)">
这还将把“路径”的参数传递到当前位置。
尝试使用此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes">
<xsl:output method="text"/>
<xsl:key name="places" match="place" use="belongsTo/@active" />
<xsl:param name="idno" select="'CA'" />
<xsl:template match="/*">
<xsl:apply-templates select="place[idno = $idno]" />
</xsl:template>
<xsl:template match="place">
<xsl:param name="previous" />
<xsl:variable name="new" select="$previous[normalize-space()], placeName" />
<xsl:text>idno {idno}: </xsl:text>
<xsl:value-of select="$new" separator=", " />
<xsl:text> </xsl:text>
<xsl:apply-templates select="key('places', idno)">
<xsl:with-param name="previous" select="$new" />
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
这是使用 XSLT 1.0 的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:key name="parent" match="place" use="idno" />
<xsl:template match="place">
<xsl:choose>
<xsl:when test="not(belongsTo)">
<xsl:text>idno </xsl:text>
<xsl:value-of select="idno" />
<xsl:text>: </xsl:text>
<xsl:value-of select="placeName" />
<xsl:text> </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="belongsTo"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="belongsTo">
<xsl:text>idno </xsl:text>
<xsl:value-of select="../idno" />
<xsl:text>: </xsl:text>
<xsl:apply-templates select="key('parent', @active)" mode="path"/>
<xsl:value-of select="../placeName" />
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="place" mode="path">
<xsl:apply-templates select="key('parent', belongsTo/@active)" mode="path"/>
<xsl:value-of select="placeName" />
<xsl:text>, </xsl:text>
</xsl:template>
</xsl:stylesheet>
结果
idno CA: City A
idno DB: City A, District B
idno DC: City A, District C
idno SD: City A, District B, Street D
idno SD: City A, District C, Street D
idno SE: City A, Street E