Mam taki arkusz xml:
<houses>
<house number="1">
<mainroom>
<roomprice>5</roomprice>
<roomtax>2</roomtax>
</mainroom>
<roompricefull>
<price value="8"/>
</roompricefull>
</house>
<house number="2">
<mainroom>
<roomprice>3</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="7"/>
</roompricefull>
</house>
<house number="3">
<mainroom>
<roomprice>9</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="4"/>
</roompricefull>
</house>
<house number="4">
<mainroom>
<roomprice>12</roomprice>
<roomtax>3</roomtax>
</mainroom>
<roompricefull>
<price value="6"/>
</roompricefull>
</house>
</houses>
Musiałem więc zmienić wartość atrybutu „value” w elemencie „price” w każdym z „domu” na sumę wartości „roomprice” i „roomtax”
Napisałem taką transformację xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="PriceChange" match="price[parent::roompricefull]">
<xsl:copy>
<xsl:variable name="sn" select="../../@number"/>
<xsl:variable name="TaxValue" select="number(//house[@number=string($sn)]/mainroom/roomtax)"/>
<xsl:variable name="BaseValue" select="number(//house[@number=string($sn)]/mainroom/roomprice)"/>
<xsl:attribute name="value">
<xsl:value-of select="string($TaxValue+$BaseValue)"/>
</xsl:attribute>
<!--xsl:for-each select="/houses/house">
<xsl:sort select="houses/house[$sn]/roompricefull/@value"/>
</xsl:for-each-->
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Ale kiedy zacząłem pracować nad sortowaniem elementów „domu” według mojej nowej wartości, napotkałem problemy. Właściwie nie rozumiem, dlaczego to nie działa, więc skomentowałem mój ostatni z kilkudziesięciu przykładów w up code.
Mam to:
<houses>
<house number="1">
<mainroom>
<roomprice>5</roomprice>
<roomtax>2</roomtax>
</mainroom>
<roompricefull>
<price value="7"/>
</roompricefull>
</house>
<house number="2">
<mainroom>
<roomprice>3</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="4"/>
</roompricefull>
</house>
<house number="3">
<mainroom>
<roomprice>9</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="10"/>
</roompricefull>
</house>
<house number="4">
<mainroom>
<roomprice>12</roomprice>
<roomtax>3</roomtax>
</mainroom>
<roompricefull>
<price value="15"/>
</roompricefull>
</house>
</houses>
Ale oczekiwany wynik to:
<houses>
<house number="4">
<mainroom>
<roomprice>12</roomprice>
<roomtax>3</roomtax>
</mainroom>
<roompricefull>
<price value="15"/>
</roompricefull>
</house>
<house number="3">
<mainroom>
<roomprice>9</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="10"/>
</roompricefull>
</house>
<house number="1">
<mainroom>
<roomprice>5</roomprice>
<roomtax>2</roomtax>
</mainroom>
<roompricefull>
<price value="7"/>
</roompricefull>
</house>
<house number="2">
<mainroom>
<roomprice>3</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="4"/>
</roompricefull>
</house>
</houses>
Byłoby wspaniale, gdybyś mógł mi pomóc w sortowaniu i wyjaśnianiu, dlaczego mój przykład nie działa. Wygląda na to, że nie rozumiem znaczenia
2 odpowiedzi
byłoby wspaniale, gdybyś pomógł mi w sortowaniu
To jest prawidłowe podejście XSLT 1.0.
Zwróć uwagę na prawidłowe użycie xsl:sort
, które wymaga:
- typ danych do określenia, jako ciąg domyślny, podczas gdy potrzebujemy tutaj liczba
- najlepsze wykorzystanie sortowania wewnątrz
xsl:apply-templates
- zastosowanie sortowania z kluczami sortowania dokumentu wejściowego połączonymi zgodnie z wymaganiami (suma).
należy również określić porządek sortowania jako domyślny
ascending
<xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="houses"> <xsl:copy> <xsl:apply-templates select="house"> <xsl:sort select="mainroom/roomprice + mainroom/roomtax" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="price/@value"> <xsl:value-of select=" ../../../mainroom/roomprice + ../../../mainroom/roomtax"/> </xsl:template>
wyjaśnienie, dlaczego mój przykład nie działa
Twoja transformacja nie działa głównie dlatego, że próbujesz posortować elementy w niewłaściwym kontekście (wewnątrz szablonu pasującego do głębokiego elementu potomnego w drzewie). Ponadto:
- próbujesz posortować, wskazując klucz sortowania według bezwzględnego wzorca XPath.
- nie określasz potrzebnych
xsl:sort
atrybutów - chciałbyś, aby końcowe elementy były posortowane według wartości obliczonej później i nieobecnej w dokumencie wejściowym. To nie jest właściwe podejście. Należy zawsze używać wartości obecnych w dokumencie wejściowym, ostatecznie łącząc je poprawnie.
Sortuj według nowej ceny:
<xsl:template match="/">
<xsl:for-each select="house">
<xsl:sort select="mainroom/roomprice + mainroom/roomtax"/>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
Jak wcześniej:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Dostosuj cenę w wynikach:
<xsl:template match="roompricefull">
<roompricefull>
<price value="{../mainroom/roomprice + ../mainroom/roomtax}"/>
</roompricefull>
</xsl:template>
Podobne pytania
Nowe pytania
xml
XML (Extensible Markup Language) to ustrukturyzowany format dokumentu definiujący zasady kodowania tekstu. Używając tego znacznika, należy uwzględnić dodatkowe znaczniki, takie jak język programowania, zestawy narzędzi, używane technologie XML i inne znaczniki opisujące środowisko, w którym pojawił się problem. Elastyczność XML nadaje się do szerokiej gamy zastosowań do przesyłania danych przez ludzi i maszyny, dlatego należy być konkretnym, jeśli chodzi o narzędzia i biblioteki.