2

我需要以特定顺序处理(具有它们的任何节点的属性)。例如:

<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,在实际情况下,有几十个属性,而不仅仅是八个。

4

1 回答 1

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>
于 2012-04-21T09:38:42.477 回答