希望的輸出可以通過組合選擇匹配模板的順序和(而不是如果xsl-if
)xsl-choose
來創建元素來實現。
我發明了一個任意的<root>
元素來補償你的示例xml中缺少的元素。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- always start out matching the document root -->
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<!-- match the root element (not shown in your example) -->
<xsl:template match="root">
<xsl:element name="product">
<!-- apply templates in the desired order, specifically selecting matching 'data' elements -->
<xsl:apply-templates select="data[name/text() = 'id']" />
<xsl:apply-templates select="data[name/text() = 'att1']" />
<xsl:apply-templates select="data[name/text() = 'att2']" />
<xsl:apply-templates select="data[name/text() = 'status']" />
</xsl:element>
</xsl:template>
<xsl:template match="data">
<!-- choose the desired output element based on the current data/name text -->
<xsl:choose>
<xsl:when test="./name[text() = 'id']">
<xsl:element name="id">
<xsl:value-of select="./value" />
</xsl:element>
</xsl:when>
<xsl:when test="./name[text() = 'att1']">
<xsl:element name="color">
<xsl:value-of select="./value" />
</xsl:element>
</xsl:when>
<xsl:when test="./name[text() = 'att2']">
<xsl:element name="size">
<xsl:value-of select="./value" />
</xsl:element>
</xsl:when>
<xsl:when test="./name[text() = 'status']">
<xsl:element name="avail">
<xsl:value-of select="./value" />
</xsl:element>
</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
有關XSLT最常見的誤解是試圖xsl-foreach
- 使用匹配模板是要走的路,但它可以是很難表達所需的XPath來獲得所需的條件。
「有沒有一種方法可以讓我不必使用xsl-if,並且實際上可以改變屬性的順序?」。這是令人困惑的。您的輸入XML和所需的輸出都不包含任何屬性。而輸入沒有根元素。 – mzjn
@mzjn對不起,混淆,屬性是指產品屬性(顏色,大小等)。 – minus