2012-09-19 2 views
2

필자는 임의로 많은 튜플을 가진 좌표 튜플 목록을 공백으로 구분했습니다. 각 튜플은 공백으로 구분 된 2 차원 좌표 목록으로 구성됩니다. 예 : "1.1 2.8 1.2 2.9"는 POINT (1.1 2.8)에서 POINT (1.2 2.9)까지의 선을 나타냅니다. 대신 "1.1,2.8 1.2,2.9"가 필요합니다. XSLT를 사용하여 숫자 쌍 사이의 쉼표를 공백으로 대체하는 방법은 무엇입니까? 나는 "문자열 (gml : LinearRing/gml : posList)"을 가지고있다.XSLT를 사용하여 좌표 구분 기호를 튜플 목록으로 바꾸는 방법?

GML 3.1.1 기능을 지오메트리와 함께 내보내는 Java 웹 서비스에서 사용됩니다. 이 서비스는 XSLT를 사용하여 GML 문서를 KML 문서로 변환하여 KML 출력 (선택 사항)을 지원합니다 (적어도 "중요한"것으로 간주되는 청크). XSLT 1.0에 잠겨 있으므로 XSLT 2.0의 정규식은 옵션이 아닙니다.

GML은 lat/lon을 사용하고 KML은 lon/lat를 사용합니다. 그것은 XSLT 이전에 처리되고 있습니다 만, XSLT로 처리하는 것도 좋을 것입니다.


해결책을 제공해 주셔서 감사합니다. 내 필요에 맞게 약간 수정 했으므로 다른 사람들에게 도움이 될 수 있도록 여기에 포함시킬 것입니다. 2 차원 튜플을 가정하고 좌표 목록을 통해 재귀를 수행합니다.

축 스왑 (lon/lat 용 lat/lon, GML 및 KML 사양 별) 및 공간 튜너의 좌표 구분 기호를 공백 문자 '에서 쉼표'로 변경하는 두 가지 기능을 수행합니다.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gml="http://www.opengis.net/gml" exclude-result-prefixes="gml"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <!-- other portions omitted --> 

    <xsl:template match="gml:pos"> 
     <xsl:call-template name="coordinateSequence"> 
     <xsl:with-param name="coords" select="normalize-space(string(.))" /> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template match="gml:posList"> 
     <xsl:call-template name="coordinateSequence"> 
     <xsl:with-param name="coords" select="normalize-space(string(.))" /> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="coordinateSequence"> 
     <xsl:param name="coords" /> 
     <xsl:if test="string-length($coords) > 0"> 
     <xsl:variable name="lat" select="substring-before($coords, ' ')" /> 
     <xsl:variable name="lon"> 
      <xsl:value-of select="substring-before(substring-after($coords, ' '), ' ')" /> 
      <xsl:if test="string-length(substring-before(substring-after($coords, ' '), ' ')) = 0"> 
       <xsl:value-of select="substring-after($coords, ' ')" /> 
      </xsl:if> 
     </xsl:variable> 
     <xsl:variable name="remainder" select="substring-after(substring-after($coords, ' '), ' ')" /> 

     <xsl:value-of select="concat($lon, ',', $lat)" /> 
     <xsl:if test="string-length($remainder) > 0"> 
      <xsl:value-of select="' '" /> 
      <xsl:call-template name="coordinateSequence"> 
       <xsl:with-param name="coords" select="$remainder" /> 
      </xsl:call-template> 
     </xsl:if> 
     </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

답변

3

이 변환 (또한 중간 단계를 나타낸다)이 XML 문서에 적용

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:template match="/*"> 
    <xsl:variable name="vNorm" select="normalize-space()"/> 
    <xsl:variable name="vP1" select= 
    "concat(substring-before(., ' '), ',', 
      substring-before(substring-after($vNorm, ' '),' ') 
     )"/> 

    <xsl:variable name="vPart2" select="substring-after(substring-after($vNorm,' '),' ')"/> 

    <xsl:variable name="vP2" select= 
    "concat(substring-before($vPart2, ' '), ',', 
      substring-after($vPart2, ' ') 
     )"/> 


    <xsl:value-of select="$vP1"/> 
========== 
    <xsl:value-of select="$vP2"/> 
========== 
    <xsl:value-of select="concat($vP1, ' ', $vP2)"/> 
</xsl:template> 
</xsl:stylesheet> 

:

<t>1.1 2.8 1.2 2.9</t> 

가 원하는 정확한 결과를 생성 (마지막 줄) :

,
1.1,2.8 
========== 
    1.2,2.9 
========== 
    1.1,2.8 1.2,2.9 

의 편의를 위해가이 코드를 각각 호출 할 명명 된 템플릿에 배치 할 수는 선 원 :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:template match="/*"> 
    <xsl:call-template name="convertLine"/> 
</xsl:template> 

<xsl:template name="convertLine"> 
    <xsl:param name="pStr" select="."/> 

    <xsl:variable name="vNorm" select="normalize-space($pStr)"/> 
    <xsl:variable name="vP1" select= 
    "concat(substring-before($pStr, ' '), ',', 
      substring-before(substring-after($vNorm, ' '),' ') 
     )"/> 

    <xsl:variable name="vPart2" select="substring-after(substring-after($vNorm,' '),' ')"/> 

    <xsl:variable name="vP2" select= 
    "concat(substring-before($vPart2, ' '), ',', 
      substring-after($vPart2, ' ') 
     )"/> 


    <xsl:value-of select="concat($vP1, ' ', $vP2)"/> 
</xsl:template> 
</xsl:stylesheet> 
+0

난 당신이 게시 감사 해요; 나는 유사한 솔루션을 작성하고 있었고, 전체적으로 생각할 때 "하위 문자열 기능이 가장 훌륭한 솔루션이라고 생각합니다." 우리가 당신의 솔루션의 우아함을 믿을 수있게, 나는 만족합니다. :) – ABach

+0

@ Bach, 많은 좌표 (N- 차원 2 점)가있는 튜플에 대한 솔루션은 상당히 다를 것입니다. 그러나 N = 2에서이 작업을 수행 할만한 가치가 없습니다. –

+0

임의로 큰 좌표 목록을 지원해야했습니다. 그러나 약간의 재귀를 추가하는 것이 트릭을 만들었습니다. 다른 사람들이 유용하다고 생각하는 경우를 대비하여 내 자신의 답변을 추가하겠습니다. – kuloch

0
<xsl:for-each select="tokenize($in, ' ')"> 
    <xsl:value-of select="concat($t, if (position() mod 2) = 0 then ' ' else ',')"/> 
</xsl:for-each> 
+0

XSLT 2.0을 사용할 때 이상적인 솔루션 일 수 있습니다. sadDimension 속성에서 $ dim 세트로 "mod 2"를 "mod $ dim"로 변경하여 N 차원 좌표를 지원할 수도 있습니다. 불행히도 XSLT 1.0으로 제한됩니다. – kuloch

관련 문제