如何基于列表索引条件使用XSLT提取XML?

时间:2018-12-12 16:15:54

标签: xml xslt saxon

我有一个<segment>列表,可以在<list>内出现2-4次。如何访问基于索引的细分以将其解析为csv字符串?

示例:

<root>
<list>
    <segment>
        <origin>new york</origin>
    </segment>
    <segment>
        <origin>san francisco</origin>
    </segment>
    <segment>
        <origin>London</origin>
    </segment>
    <segment>
        <origin>Berlin</origin>
    </segment>
</list>
<list>
    <segment>
        <origin>new york</origin>
    </segment>
    <segment>
        <origin>Berlin</origin>
    </segment>
</list>
</root>

我的目标:提取中间部分,如果不存在,则留空。所需的输出将是:

sanfrancisco;london //both segments 2 + 3 filled
'';''               //both segments 2 + 3 empty

因此,应该始终忽略第一段和最后一段。介于两者之间的所有段均应提取<origin>标签。如果两者之间没有片段,则应添加一个空字段。

<xsl:template match="root">
    <xsl:for-each select="//list//segment">
        <!-- of course this is wrong, because it selects just all origins. -->
        <xsl:value-of select=".//origin" separator=";"/>
    </xsl:for-each>
</xsl:template>

问题:如何将以下内容转换为xslt(伪代码):

if (segment.size <= 2) write '';''
if (segment.size <= 3) write segment[1].origin;''
if (segment.size <= 4) write segment[1].origin;segment[2].origin

1 个答案:

答案 0 :(得分:2)

如果您没有忽略头和尾段的逻辑,那么您实际上应该这样做...

<xsl:for-each select="//list">
    <xsl:value-of select="segment/origin" separator=";"/>
    <xsl:text>&#10;</xsl:text>
</xsl:for-each>

要忽略第一个和最后一个,但尚未添加空白条目,请执行此操作...

<xsl:for-each select="//list">
    <xsl:value-of select="segment[not(position() = (1, last()))]/origin" separator=";"/>
    <xsl:text>&#10;</xsl:text>
</xsl:for-each>

要添加空白条目(假设每个列表确实不超过4个细分),请执行此操作...

<xsl:variable name="blank" select='"&apos;&apos;"' />
<xsl:for-each select="//list">
    <xsl:value-of select="(segment[not(position() = (1, last()))]/origin, $blank, $blank)[position() le 2]" separator=";"/>
    <xsl:text>&#10;</xsl:text>
</xsl:for-each>