改进了 XSL 脚本,其中包含 XML 文件中的链接并应用模板



下面是一些XSL脚本:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msa="http://www.publictalksoftware.co.uk/msa">
  <xsl:output method="html" indent="yes" version="4.01"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    doctype-public="//W3C//DTD XHTML 1.0 Transitional//EN"/>
  <xsl:variable name="DutyHistory" select="document('DutyAssignHistory.XML')"/>
  <xsl:template match="/">
    <html>
      <head>
        <title>Test</title>
      </head>
      <body>
        <xsl:for-each select="MeetingWorkBook/Meeting">
          <p>
            <xsl:value-of select ="Date/@ThisWeek"/>
          </p>
          <xsl:variable name="Week" select="Date/@ThisWeek"/>
          <table>
            <tr>
              <td>Sound</td>
              <td>
                <xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment[@Index='1' and @IndexType='Fixed']"/>
              </td>
            </tr>
            <tr>
              <td>Platform</td>
              <td>
                <xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment[@Index='5' and @IndexType='Fixed']"/>
              </td>
            </tr>
            <tr>
              <td>Left Mike</td>
              <td>
                <xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment[@Index='7' and @IndexType='Fixed']"/>
              </td>
            </tr>
            <tr>
              <td>Right Mike</td>
              <td>
                <xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment[@Index='8' and @IndexType='Fixed']"/>
              </td>
            </tr>
            <tr>
              <td>Public Talk Chairman</td>
              <td>
                <xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment[@Index='4' and @IndexType='Custom']"/>
              </td>
            </tr>
            <tr>
              <td>Watchtower Reader</td>
              <td>
                <xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment[@Index='5' and @IndexType='Custom']"/>
              </td>
            </tr>
          </table>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

如您所见,它正在另一个XML文档中链接以供参考。以下是文件中链接的一个示例:

<?xml version="1.0" encoding="utf-8"?>
<DutyAssignmentHistory xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.publictalksoftware.co.uk/msa">
  <DutyAssignments>
    <DutyAssignmentEntry Date="2018-01-04" Week="W20180101" Template="0" Mode="Midweek">
      <Assignment Index="2" IndexType="Fixed">Name 1</Assignment>
      <Assignment Index="5" IndexType="Fixed">Name 2</Assignment>
      <Assignment Index="7" IndexType="Fixed">Name 3</Assignment>
      <Assignment Index="8" IndexType="Fixed">Name 4</Assignment>
      <Assignment Index="13" IndexType="Fixed">Name 5</Assignment>
      <Assignment Index="14" IndexType="Fixed">Name 6</Assignment>
    </DutyAssignmentEntry>
  </DutyAssignments>
</DutyAssignmentHistory>

可能用户可能希望引用XML中的信息并按照他们喜欢的方式显示它,但我想向他们展示最简单的方法。

如您所见,有几个标准:

  • Week (WYYYYMMDD(
  • Mode ( MidweekWeekendWeekly (
  • Template(0 或更高(

以上内容将过滤到正确的作业周。然后,要确定实际分配,请执行以下操作:

  • Index(数值(
  • IndexType ( FixedCustomFixedCustom (

我可以以任何方式使用模板(可能带有变量(来简化代码,因为它变得重复?

您可以使用模板并传递参数,或者在 XSLT 2.0 或更高版本中还可以定义一个函数,这使得它更易于使用并节省一些键入。但是对于您当前正在做的事情,变量和一些谓词过滤器似乎是最简单和容易的。

最简单易行的方法是将变量与周末赋值绑定,然后应用谓词过滤器以选择具有@Index@IndexType的变量:

<xsl:variable name="Week" select="Date/@ThisWeek"/>
<xsl:variable name="weekend-assignments"
             select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments
                /msa:DutyAssignmentEntry[@Week=$Week and @Mode='Weekend']/msa:Assignment"/>
<table>
  <tr>
    <td>Sound</td>
    <td>
      <xsl:value-of select="$weekend-assignments[@Index='1' and @IndexType='Fixed']"/>
      </td>
  </tr>

如果使变量包含一组未筛选的Assignment元素,则可以在谓词中执行所有筛选:

<xsl:variable name="Week" select="Date/@ThisWeek"/>
<xsl:variable name="assignments"
             select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments
                /msa:DutyAssignmentEntry/msa:Assignment"/>
<table>
  <tr>
    <td>Sound</td>
    <td>
      <xsl:value-of 
           select="$assignments[@Index='1' and @IndexType='Fixed']
                               [..[@Week=$Week and @Mode='Weekend' and @Template='0']]"/>
      </td>
  </tr>

如果要合并用于生成列的逻辑,可以定义一个模板msa:Assignment

<xsl:template match="msa:Assignment">
  <td>
    <xsl:value-of select="."/>
  </td>
</xsl:template>

然后像这样使用它:

<table>
  <tr>
    <td>Sound</td>
    <xsl:apply-templates select="$weekend-assignments[@Index='1' and @IndexType='Fixed']"/>

如果要合并用于生成行的逻辑,可以定义一个msa:Assignment模板,并为第一列发送参数:

<xsl:template match="msa:Assignment">
    <xsl:param name="label"/>
    <tr>
        <td><xsl:value-of select="$label"/></td>
        <td>
            <xsl:value-of select="."/>
        </td>
    </tr>
</xsl:template>

然后像这样使用它:

<table>
  <xsl:apply-templates select="$weekend-assignments[@Index='1' and @IndexType='Fixed']">
    <xsl:with-param name="label" select="'Sound'"/>
  </xsl:apply-templates>

最新更新