演练:调试 XSLT 样式表

此演练中的步骤演示如何使用 XSLT 调试程序。 步骤包括查看变量、设置断点和逐行执行代码。 调试器使你可以一次执行一行代码。

若要为此演练做好准备,请先将两个示例文件复制到本地计算机上。 一个文件是样式表,另一个是将用作样式表的输入的 XML 文件。 在此演练中,我们使用的样式表会查找成本低于平均书价的所有书籍。

注意

XSLT 调试器仅在 Visual Studio Professional 和 Enterprise 版本中提供。

“启动调试”

  1. 在“文件”菜单中,选择“打开”>“文件”。

  2. 找到 below-average.xsl 文件,然后选择“打开”。

    样式表会在 XML 编辑器中打开。

  3. 在文档属性窗口的“输入”字段上单击“浏览”按钮 (...)。 (如果“属性”窗口不可见,请在编辑器中打开的文件上右键单击任意位置,然后选择“属性”。)

  4. 找到 books.xml 文件,然后选择“打开”。

    这会设置用于 XSLT 转换的源文档文件。

  5. 在 below-average.xsl 的第 12 行上设置断点。 可以通过多种方法执行此操作:

    • 在第 12 行上的编辑器边距中单击。

    • 单击第 12 行上的任意位置,然后按 F9。

    • 右键单击 xsl:if 开始标记,然后选择“端点”>“插入断点”。

      Insert breakpoint in XSL file in Visual Studio

  6. 在菜单栏上,选择“XML”>“开始调试 XSLT”(或按 Alt+F5)。

    调试过程随即开始。

    在编辑器中,调试器位于样式表的 xsl:if 元素上。 名为 below-average.xml 的另一个文件会在编辑器中打开;这是将在处理输入文件 books.xml 中的每个节点时填充的输出文件。

    “自动”、“局部变量”和“监视 1”窗口会出现在 Visual Studio 窗口底部。 “局部变量”窗口显示所有局部变量及其当前值。 其中包括样式表中定义的变量,也包括调试程序在跟踪上下文中的当前节点时使用的变量。

监视窗口

我们会将两个变量添加到“监视 1”窗口,以便可以在处理输入文件时检查其值。 (如果要监视的变量已经存在,则还可以使用“局部变量”窗口检查值。)

  1. 在“调试”菜单中,选择“窗口”>“监视”>“监视 1”。

    “监视 1”窗口会成为可见状态。

  2. 在“名称”字段中键入 $bookAverage,然后按 Enter。

    $bookAverage 变量的值会显示在“值”窗口中。

  3. 在下一行中,在“名称”字段中键入 self::node(),然后按 Enter。

    self::node() 是一个计算结果为当前上下文节点的 XPath 表达式。 self::node() XPath 表达式的值是第一个 book 节点。 此值随着转换的进度而更改。

  4. 展开 self::node() 节点,然后展开值为 price 的节点。

    Watch window during XSLT debugging in Visual Studio

    可以查看当前 book 节点的书价值并将它与 $bookAverage 值进行比较。 因为书价低于平均值,所以在继续调试过程时,xsl:if 条件应成功。

逐行执行代码

  1. 按 F5 继续。

    因为第一个 book 节点满足 xsl:if 条件,所以,该 book 节点将添加到 below-average.xml 输出文件。 调试器继续执行,直到它再次位于样式表中的 xsl:if 元素上。 调试器此时位于 books.xml 文件中的第二个 book 节点上。

    在“监视 1”窗口中,self::node() 值变为第二个 book 节点。 通过检查 price 元素的值,可以确定价格高于平均值,所以,xsl:if 条件应失败。

  2. 按 F5 继续。

    因为第二个 book 节点未满足 xsl:if 条件,所以不会将此 book 节点添加到 below-average.xml 输出文件。 调试器继续执行,直到它再次位于样式表中的 xsl:if 元素上。 调试器此时位于 books.xml 文件中的第三个 book 节点上。

    在“监视 1”窗口中,self::node() 值变为第三个 book 节点。 通过检查 price 元素的值,可以确定此价格低于平均价格。 xsl:if 条件应成功。

  3. 按 F5 继续。

    因为满足 xsl:if 条件,所以,第三个 book 节点将添加到 below-average.xml 输出文件。 XML 文档中的所有 book 节点均已处理,调试程序停止。

示例文件

下列两个文件供该演练使用。

below-average.xsl

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8"/>
  <xsl:template match="/">
    <xsl:variable name="bookCount" select="count(/bookstore/book)"/>
    <xsl:variable name="bookTotal" select="sum(/bookstore/book/price)"/>
    <xsl:variable name="bookAverage" select="$bookTotal div $bookCount"/>
    <books>
      <!--Books That Cost Below Average-->
      <xsl:for-each select="/bookstore/book">
        <xsl:if test="price &lt; $bookAverage">
          <xsl:copy-of select="."/>
        </xsl:if>
      </xsl:for-each>
    </books>
  </xsl:template>
</xsl:stylesheet>

books.xml

<?xml version='1.0'?>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore>
  <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
    <title>The Autobiography of Benjamin Franklin</title>
    <author>
      <first-name>Benjamin</first-name>
      <last-name>Franklin</last-name>
    </author>
    <price>8.99</price>
  </book>
  <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
    <title>The Confidence Man</title>
    <author>
      <first-name>Herman</first-name>
      <last-name>Melville</last-name>
    </author>
    <price>11.99</price>
  </book>
  <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
    <title>The Gorgias</title>
    <author>
      <name>Plato</name>
    </author>
    <price>9.99</price>
  </book>
</bookstore>