在嵌套For Each中的XSLT中排序

时间:2012-02-08 13:58:47

标签: xml xslt

这是我正在尝试做的事情: 我有一个学院列表,每个院系都是一个部门列表。我想显示整个部门列表,按部门名称排序,但指示教员。

XML看起来像这样:

<Faculties>

  <Faculty Name="Science">
    <Department name="dept2">
      <head>Mr X</head>
      <building>A Block</building>
      etc...
   </Department>
   <Department name="dept3">
      <head>Mr X</head>
      <building>B Block</building>
      etc...
   </Department>
  </Faculty>

  <Faculty Name="Education">
    <Department name="dept1">
      <head>Mr Y</head>
      <building>C Block</building>
      etc...
    </Department>
  </Faculty>

</Faculties>    

XSLT看起来像这样:(为了解释的目的,我简化了XSLT。)

<xsl:for-each select="Faculties">
  <xsl:sort select="DepartmentName">
  <xsl:for-each select="Departments">
    <xsl:element name="div">
      <xsl:attribute name="id"><xsl:value-of select="facultName"></xsl:attribute>
      <h3><xsl:value-of select="deptName"> - <xsl:value-of select="facultName"></h3>
      //More stuff here
    </xsl:element>
  </xsl:for-each>
</xsl:for-each>

我希望输出看起来像:

Dept1 (Education)
Head: Mr Y
Building: C Block

Dept2 (Science)
Head: Mr X
Building: A Block

Dept3 (Science)
Head: Mr X
Building: B Block

按部门名称排序的位置。

我还希望能够使用Javascript隐藏特定教师的所有部门,即隐藏ID中具有特定教职员的所有部门。

我甚至不确定我正在尝试的是否可能(或逻辑)。我唯一的另一种选择似乎是产生一个全新的部门清单,其中教师是其中一个要素。然后我只需要一个 - 每个。不幸的是,我无法真正控制XML的生成方式,所以我希望能够这样做。

我感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:8)

如果您想按名称顺序列出所有部门,无论教员如何,您都可以直接迭代部门

<xsl:for-each select="Faculty/Department">
   <xsl:sort select="@deptName" />

</xsl:for-each>

然后,要获得部门的教职员名称,您可以非常轻松地访问父元素

<xsl:value-of select="../@facultyName" />

因此,假设您有以下XML

<Faculties>
   <Faculty id="1" facultyName="Beer Drinking">
      <Department id="1" deptName="Real Ale" />
      <Department id="2" deptName="Lager" />
   </Faculty>
   <Faculty id="2" facultyName="Food">
      <Department id="3" deptName="Fish and Chips" />
      <Department id="4" deptName="Pies" />
   </Faculty>
</Faculties>

应用以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>

   <xsl:template match="/Faculties">
      <xsl:apply-templates select="Faculty/Department">
         <xsl:sort select="@deptName" />
      </xsl:apply-templates>
   </xsl:template>

   <xsl:template match="Department">
      <div id="{../@facultyName}">
      <h3><xsl:value-of select="concat(@deptName, ' - ', ../@facultyName)" /></h3>
      </div>
   </xsl:template>
</xsl:stylesheet>

以下是输出

<div id="Food">
   <h3>Fish and Chips - Food</h3>
</div>
<div id="Beer Drinking">
   <h3>Lager - Beer Drinking</h3>
</div>
<div id="Food">
   <h3>Pies - Food</h3>
</div>
<div id="Beer Drinking">
   <h3>Real Ale - Beer Drinking</h3>
</div>

请注意,通常最好使用 xsl:apply-templates 而不是 xsl:for-each ,这就是我在XSLT中使用的内容。