2017-02-01 5 views
1

/로 현재 그룹()에서 결합 결과 XPath를-2.0XSLT - 2.0 : SaxonHE 9.7을 사용하여 하나의

내 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> 

내가 fhrs:id의 모든 중복 값 (v=)을 반환하고있어 사용 :

<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:apply-templates 한 번에 두 가지를 전달하고,이 경우, 다른 모든 요소가 geojson 출력에 쉼표 없기 때문에,

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

    ...<snip>... 

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

그러나 :이 지난 경우 다른 루틴에서 나는 테스트하기 위해 사용했습니다 .

xsl:for-each-group의 모든 출력을 하나로 결합하여 xsl:apply-templates으로 전달하거나 다른 방법으로 최종 요소를 찾는 방법이 있습니까? xsl:for-each-group 심지어 가장 좋은 방법인가요?

변수/배열을 사용하는 방법은 여러 가지가 있지만 청구서에 맞지 않는 것으로 보입니다. 당신은 last()의 문제에 관해서는

<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> 

을 변경할 수 있습니다

답변

2

, Saxonica는 https://saxonica.plan.io/issues/3122에보고 된 문제를 재현하고있다, 당신이 사용하여 last()을 사용하지 않도록 할 수 있습니다 경우에 생각 약간 다른 수표 position() gt 1, 내용을 출력하기 전에 :

<xsl:template match="/*/*/tag"> 
    <xsl:if test="position() gt 1">,</xsl:if> 
    { 

    "value" : "<xsl:value-of select="@v"/>" 

    } 
</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> 

그런 식으로 last()과 관련된 버그를 피할 수 있어야하지만 시퀀스 항목간에 쉼표 출력을 얻어야합니다.

+0

나는 이전에 이것을 시도했지만 색슨은 "하나 이상의 항목이 변수 $ duplicates (, , ...)의 값으로 허용되지 않습니다"라는 메시지를 반환했습니다. – DaveF

+0

@DaveF, 죄송합니다. 유형은 다음과 같습니다. 시퀀스의 경우'element() *'. –

+0

last()가 중복 된 것뿐만 아니라 ** 모든 ** fhrs : id 값의 합계를 반환한다는 점을 제외하고는 효과가있었습니다. 그래서 중복 변수를 적용된 템플릿에 전달했습니다 : ' \t \t \t \t \t' 는 그래서 그것을 사용 : '} '최고의 wqay에서인가> ? – DaveF