niedziela, 8 stycznia 2012

Ćwiczenie z XSLT

Zadanie polega na wydłubaniu z pliku GPX pierwszego i ostatniego elementu <time>, który jest dzieckiem elementu <trkpt>. (Nie może być po prostu <time>, bo element ten występuje także w innym kontekście.)

Coś takiego wymyśliłem:


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gpx="http://www.topografix.com/GPX/1/0">

<xsl:output method="text"/>

<xsl:param name='Position' select="'First'"/>

<xsl:template match="/" >

<xsl:for-each select='//gpx:trkpt'>

<xsl:if test="position()=1 and $Position='First'">
<xsl:value-of select='gpx:time'/>
<xsl:text>&#10;</xsl:text>
</xsl:if>

<xsl:if test="position()=last() and $Position='Last'">
<xsl:value-of select='gpx:time'/>
<xsl:text>&#10;</xsl:text>
</xsl:if>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

W praniu się okazało, że jest jeden drobny, komplikujący życie feler-nie-feler. Struktura plików GPX (w zależności od tego czym są one generowane) jest identyfikowana albo z przestrzenią nazw http://www.topografix.com/GPX/1/0 albo z http://www.topografix.com/GPX/1/1. Praktycznie żadna różnica, ale szablon przestaje działać. Aby uodpornić szablon na wersje formatu można zamienić:


<xsl:for-each select='//gpx:trkpt'>

na


<xsl:for-each select='//*[local-name()="trkpt"]'>

Teraz szablon `reaguje' na element <trkpt> z dowolnej przestrzeni nazw. Oczywiście reguła wyboru węzłów stała się teraz `mniej specyficzna', co w przypadku bardziej skomplikowanych transformacji może nie być najlepszym pomysłem, ale w przypadku tak prostego schematu jak GPX i banalnej transformacji, jak powyższa nie powinno być problemów.

Podobnie można zamienić:


<xsl:value-of select='gpx:time'/>

na:


<xsl:value-of select='*[local-name()="time"]'/>

Teraz, przykładowo uruchomienie xsltproc (opisany wyżej szablon jest zawartością pliku gpxtimestamp.xsl):


xsltproc --param Position '"First"' gpxtimestamp.xsl 20120107.xml
xsltproc --param Position '"Last"' gpxtimestamp.xsl 20120107.xml

Wypisuje odpowiednio zawartość pierwszego i ostatniego elementu <time>.

Brak komentarzy:

Prześlij komentarz