XSLT-2.0:将current-group()的结果合并为一个

时间:2017-02-01 14:59:22

标签: xslt xpath xslt-2.0

使用SaxonHE 9.7 / XPath-2.0

我的XML:

<osm>
  <node>
    <tag k="fhrs:id" v="204258"/>
    <tag k="name" v="King of Wessex"/>
  </node>
  <node>
    <tag k="fhrs:id" v="139245"/>
    <tag k="name" v="The Royal Oak"/>
  </node>
  <node>
    <tag k="fhrs:id" v="204258"/>
    <tag k="name" v="The Rising Sun"/>
  </node>
  etc...
</osm>

我使用以下内容返回v=的所有重复值(fhrs:id):

 <xsl:template match="/">       
     <xsl:for-each-group select="/*/*/tag[@k='fhrs:id']" group-by="@v">
        <xsl:apply-templates select="current-group() [current-group()[2]]"/>
     </xsl:for-each-group>
 </xsl:template>

我将输出转换为geojson格式。这要求除最后一个元素之外的每个元素都以逗号结尾。在其他例程中,我使用它来测试它是否是最后一个:

<xsl:template match="/*/*/tag">
    {

     ...<snip>... 

    }<xsl:if test="position() &lt; last()">,</xsl:if>
</xsl:template> 

但是,因为在这种情况下xsl:apply-templates一次只传递两个,所以每个其他元素都缺少geojson输出中的逗号。

有没有办法将xsl:for-each-group的所有输出合并为一个,然后再将其传递给xsl:apply-templates或另一种方法来查找最终元素? xsl:for-each-group甚至是最好的方式吗?

我已经研究了使用变量/数组的各种方法,但似乎不符合要求。

1 个答案:

答案 0 :(得分:2)

您可以更改

.

<xsl:template match="/">       
     <xsl:for-each-group select="/*/*/tag[@k='fhrs:id']" group-by="@v">
        <xsl:apply-templates select="current-group() [current-group()[2]]"/>
     </xsl:for-each-group>
 </xsl:template>

至于<xsl:template match="/"> <xsl:variable name="duplicates" as="element()*"> <xsl:for-each-group select="/*/*/tag[@k='fhrs:id']" group-by="@v"> <xsl:sequence select="current-group() [current-group()[2]]"/> </xsl:for-each-group> </xsl:variable> <xsl:apply-templates select="$duplicates"/> </xsl:template> 的问题,Saxonica已经复制了https://saxonica.plan.io/issues/3122中报告的问题,我认为在您的情况下,您可以避免使用last()使用稍微不同的支票{{1} },但在输出内容之前:

last()

这样你应该能够避免与position() gt 1相关的错误,但是你应该在序列的各项之间得到一个逗号输出。