每个<leg>
记录旅行的一段。旅程按文件顺序记录。一些腿在相同位置开始和结束(例如,从MA到MA),一些腿到位(例如,从MA到CT)。一些关于起点和终点位置的数据缺失。
<trip>
<leg start="MA" stop="MA" />
<leg start="MA" stop="CT" />
<leg start="NY" />
<leg />
<leg start="DE" />
<leg stop="DE" />
<leg start="NY" stop="PA" />
</trip>
使用XSLT / XPATH 1.0,我想按照访问顺序列出一个位置:
<trip>
<place>MA</place>
<place>CT</place>
<place>NY</place>
<place>DE</place>
<place>NY</place>
<place>PA</place>
</trip>
修改
好的,我想我知道该怎么做了:
<xsl:template match="leg" mode="tour">
<xsl:if test="string(@start)">
<place><xsl:value-of select="@start"></place>
</xsl:if>
<xsl:if test="string(@end)">
<place><xsl:value-of select="@end"></place>
</xsl:if>
</xsl:template>
<xsl:variable name="rtfPlaces">
<xsl:apply-templates select="trip/leg" mode="tour" />
</xsl:variable>
<xsl:variable name="places" select="exslt:node-set($rtfPlaces)" />
<xsl:variable name="uniquePlaces" select="$places/place[1] | $places/place[.!=preceding-sibling::place[1]]" />
解决方案:确实在两次通过中处理它。通过单独写出来获取所需顺序的@start和@end。然后在第二遍中选择唯一值。
这不会让我得到输出中的trip
元素,但我认为我真的不需要它。
它确实需要节点集扩展,但也可以。
如果一切都可以完成,我不知道如何。
答案 0 :(得分:1)
这应该一次通过......
XML输入
<trip>
<leg start="MA" stop="MA" />
<leg start="MA" stop="CT" />
<leg start="NY" />
<leg />
<leg start="DE" />
<leg stop="DE" />
<leg start="NY" stop="PA" />
</trip>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
<xsl:template match="trip">
<trip>
<xsl:apply-templates/>
</trip>
</xsl:template>
<!--This is so we don't get duplicate entries
for both attributes when they are the same.-->
<xsl:template match="@stop[.=parent::*/@start]"/>
<xsl:template match="@start|@stop">
<xsl:if test="not(parent::leg/preceding-sibling::leg[1][@start = current() or @end = current()])">
<place><xsl:value-of select="."/></place>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
XML输出
<trip>
<place>MA</place>
<place>CT</place>
<place>NY</place>
<place>DE</place>
<place>NY</place>
<place>PA</place>
</trip>
您还可以添加此模板,以确保在@start
之前@stop
处理 <xsl:template match="leg">
<xsl:apply-templates select="@start"/>
<xsl:apply-templates select="@stop"/>
</xsl:template>
:
{{1}}