I. C'è un XSLT generale e pura 1,0 soluzione - semplice come questo:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<products>
<xsl:apply-templates select="*">
<xsl:sort data-type="number" select=
"price/*[not(../* < .)]"/>
</xsl:apply-templates>
</products>
</xsl:template>
</xsl:stylesheet>
II.Se price
ha altri bambini oltre a offer
e orig
- in questo caso la soluzione generale I. sopra (così come le altre due risposte a questa domanda) non funziona correttamente.
ecco una soluzione corretta per questo caso:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<products>
<xsl:apply-templates select="*">
<xsl:sort data-type="number" select=
"sum(price/orig[not(../offer <= .)])
+
sum(price/offer[not(../orig < .)])
"/>
</xsl:apply-templates>
</products>
</xsl:template>
</xsl:stylesheet>
III. Se sappiamo che offer
mai supera orig
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<products>
<xsl:apply-templates select="*">
<xsl:sort data-type="number"
select="price/offer | price/orig[not(../offer)]"/>
</xsl:apply-templates>
</products>
</xsl:template>
</xsl:stylesheet>
IV. Verifica:
Tutte e tre le trasformazioni di cui sopra, se applicato al documento XML fornito:
<products>
<product>
<name>Product 1</name>
<price>
<orig>15</orig>
<offer>10</offer>
</price>
</product>
<product>
<name>Product 2</name>
<price>
<orig>13</orig>
<offer>12</offer>
</price>
</product>
<product>
<name>Product 3</name>
<price>
<orig>11</orig>
</price>
</product>
</products>
produrre il desiderato, risultato corretto:
<products>
<product>
<name>Product 1</name>
<price>
<orig>15</orig>
<offer>10</offer>
</price>
</product>
<product>
<name>Product 3</name>
<price>
<orig>11</orig>
</price>
</product>
<product>
<name>Product 2</name>
<price>
<orig>13</orig>
<offer>12</offer>
</price>
</product>
</products>
Solution II è l'unico di i tre che producono ancora il risultato corretto quando applicati a questo documento XML (aggiunto unfiglio a price
):
<products>
<product>
<name>Product 1</name>
<price>
<orig>15</orig>
<offer>10</offer>
<minAcceptable>8</minAcceptable>
</price>
</product>
<product>
<name>Product 2</name>
<price>
<orig>13</orig>
<offer>12</offer>
<minAcceptable>6</minAcceptable>
</price>
</product>
<product>
<name>Product 3</name>
<price>
<orig>11</orig>
<minAcceptable>7</minAcceptable>
</price>
</product>
</products>
Do atto che nessuna delle altre risposte elabora correttamente questo documento XML.
+1 Molto elegante - bel lavoro, @DimitreNovatchev. Vorrei tuttavia sostenere che la soluzione II non è appropriata alla domanda (poiché affronta una situazione mai descritta dal PO) e pertanto non dovrebbe essere utilizzata come prova di inadeguatezza in altre risposte. :) – ABach
@ABach, prego. Per quanto riguarda la rilevanza, entrambe le soluzioni 1. e 3. stanno seguendo esattamente il documento XML dell'OP. La soluzione 2 ci dà la conoscenza su cosa fare in una situazione leggermente diversa, quando altre soluzioni non funzionano. La conoscenza è potere, non ti capisci così? –
Lo comprerò. :) – ABach