I. 一般的で純粋な XSLT 1.0 ソリューションがあります。これは次のように単純です。
<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>
Ⅱ.andprice
に加えて他の子を持つ場合offer
orig
- この場合、一般解I . 上記(およびこの質問に対する他の2つの回答)は正しく機能しません。
この場合の正しい解決策は次のとおりです。
<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. offer
を超えないことがわかっている場合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. 検証:
上記の 3 つの変換すべてを、提供された XML ドキュメントに適用すると、次のようになります。
<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>
必要な正しい結果を生成します。
<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>
解決策 II は、この XML ドキュメントに適用したときに正しい結果を生成する 3 つの唯一のものですminAcceptable
( に子を追加しました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>
他の回答では、この XML ドキュメントが正しく処理されないことに注意してください。