Mam blok XSLT, które mogą być stosowane kilka razy w ciągu transformacji. Ale chcę, aby faktycznie działał tylko przy pierwszym użyciu, powinien zostać pominięty przez wszystkie subskrybujące czasy. Jak mam to zrobic?W XSLT, mogę uruchomić szablon tylko raz
Jako przykład, jest to rodzaj rzeczy chcę zrobić: W arkuszu stylów zdefiniować zmienną globalną:
<xsl:variable name="run_once" select="0"/>
Następnie Mam szablon, który nazywa się kilka razy:
<xsl:template name="some_template">
<xsl:if test="$run_once != 1">
<xsl:variable name="run_once" select="1"/>
<xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text>
</xsl:if>
</xsl:template>
To nie działa, oczywiście, ponieważ zmienne nie mogą być zmienione, tylko przeciążone. Tak więc, gdy some_template wyjdzie z $ run_once będzie ponownie 0 i tekst zostanie zastosowany za każdym razem, gdy zostanie wywołany szablon. Czy istnieje jakiś typ funkcji ifdef lub inny obiekt globalny, który można ustawić?
Jeśli jesteś zainteresowany, dlaczego chcę to zrobić, poniżej znajduje się bardziej szczegółowe wyjaśnienie mojego problemu i rozwiązanie użyłem:
- Mój wkład jest dane w surowym formacie XML, moje wyjście jest zgłoś w formacie WordML.
- Na wejściu mam serię węzłów (o nazwie theNode). Niektóre, ale nie wszystkie, muszą być wyświetlane na wyjściu. Węzeł powinien być wyświetlany tylko wtedy, gdy prawda jest prawdziwa (hairyLogic jest oczywiście długi i kompleks).
- theNode również mają typ (przechowywany w pod-węzeł). Na wejściu wszystkie węzły tego samego typu będą zawsze grupowane razem. Na wyjściu wszystkie węzły tego samego typu powinny być zgrupowane pod konkretnym nagłówkiem tego typu ( ) dla każdego typu powinien być tylko jeden nagłówek dla każdego typu ).
To rozwiązanie skończyło się przy użyciu:
...
<xsl:apply-templates select="theNode[hairyLogic]"/>
...
<xsl:template match="theNode">
<xsl:if test="count(preceding-sibling::theNode[type = current()/type and hairyLogic])=0">
<xsl:choose>
<xsl:when test="type = 'TYPE1a' or type = 'TYPE1b'">
<xsl:call-template name="TYPE1Heading"/>
</xsl:when>
<xsl:when test="type = 'TYPE2'">
<xsl:call-template name="TYPE2Heading"/>
</xsl:when>
</xsl:choose>
</xsl:if>
...
</xsl:template>
wybrałem używać nazwanych szablony dla nagłówków, ponieważ zawierają one podstawowe WordML, który nie zależy od żadnych danych w formacie XML wejściowego.
Nie podoba mi się to rozwiązanie, ponieważ hairyLogic jest powtarzany, a instrukcja if jest zawiła i trudna do odczytania. Może masz lepsze rozwiązanie, które nie wymaga zmiennych zmiennych?
"co jest odpowiednikiem XSLT pythonic? Xslt-y?" - jest "deklaratywny" –
Tak, mam ograniczenia, których nie szczegółowo opisałem (dodano do pytania, jeśli jesteś zainteresowany). Rozwiązałem problem tak, jak opisujesz. Nie podoba mi się to, ponieważ "somelogiczny" jest długi, niechlujny i teraz jest powtarzany kilka razy. Nie byłoby tak źle, gdybym mógł dyktować, kiedy kod XPATH jest analizowany, tak jak ja w innych językach funkcjonalnych. Wtedy mógłbym zapisać zły fragment "somelogiczny" w zmiennej i wstawić go w moje wyrażenia, gdy jest to potrzebne. – oillio