我需要按特定顺序处理属性(具有它们的任何节点)。例如:
<test>
<event
era ="modern"
year ="1996"
quarter = "first"
day = "13"
month= "January"
bcad ="ad"
hour ="18"
minute = "23"
>The big game began.</event>
<happening
era ="modern"
day = "18"
bcad ="ad"
month= "February"
hour ="19"
minute = "24"
>The big game ended.</happening>
<other>Before time existed.</other>
</test>
这个
<xsl:template match="test//*">
<div>
<xsl:apply-templates select="@*" />
<xsl:apply-templates />
</div>
</xsl:template>
<xsl:template match="@*">
<span class="{name()}">
<xsl:value-of select="."/>
</span>
</xsl:template>
会根据我的需要格式化。也就是说,我会得到
<div><span class="era">modern</span>
<span class="year">1996</span>
<span class="quarter">first</span>
<span class="day">13</span>
<span class="month">January</span>
<span class="bcad">ad</span>
<span class="hour">18</span>
<span class="minute">23</span>The big game began.</div>
<div><span class="era">modern</span>
<span class="day">18</span>
<span class="bcad">ad</span>
<span class="month">February</span>
<span class="hour">19</span>
<span class="minute">24</span>The big game ended.</div>
<div>Before time existed.</div>
(虽然没有我在这里添加的新内容以便易读)。
但属性的顺序不一定是正确的。
要解决此问题,我可以将<xsl:apply-templates select="@*" />
更改为<xsl:call-template name="atts" />
并添加以所需顺序应用模板的模板,如下所示:
<xsl:template match="test//*">
<div>
<xsl:call-template name="atts" />
<xsl:apply-templates />
</div>
</xsl:template>
<xsl:template name="atts">
<xsl:apply-templates select="@era" />
<xsl:apply-templates select="@bcad" />
<xsl:apply-templates select="@year" />
<xsl:apply-templates select="@quarter" />
<xsl:apply-templates select="@month" />
<xsl:apply-templates select="@day" />
<xsl:apply-templates select="@hour" />
<xsl:apply-templates select="@minute" />
</xsl:template>
<xsl:template match="@*">
<span class="{name()}">
<xsl:value-of select="."/>
</span>
</xsl:template>
这是以指定顺序处理属性的最佳实践方法吗?我一直想知道是否有使用密钥或全局变量的方法。
我需要使用XSLT 1.0,在实际情况中,有几十个属性,而不仅仅是八个。
答案 0 :(得分:1)
与元素相比,例如,XML中的属性顺序并不重要,即XPath和XSLT可以按任何顺序处理它们。因此,强制给定订单的唯一方法是以某种方式指定它。一种方法是在上一个代码示例中明确地调用它们。您还可以提取所有属性名称并将它们存储在单独的XML文件中,例如,
之类的东西<attributes>
<attribute>era</attribute>
<attribute>year</attribute>
<attribute>month</attribute>
...
<attributes>
现在您可以使用document()函数加载这些元素并迭代所有属性元素:
<xsl:variable name="attributes" select="document('attributes.xml')//attribute"/>
...
<xsl:template match="*">
<xsl:variable name="self" select="."/>
<xsl:for-each select="$attributes">
<xsl:apply-templates select="$self/@*[name()=current()]"/>
</xsl:for-each>
</xsl:template>