XSLT 1.0 - 用 HTML 包装的多个子节点模板

Posted

技术标签:

【中文标题】XSLT 1.0 - 用 HTML 包装的多个子节点模板【英文标题】:XSLT 1.0 - Multiple Child Nodes template wrapped with HTML 【发布时间】:2020-12-12 17:56:51 【问题描述】:

我在 XML 的 XSLT 转换中遇到了 For-Each 的一些问题。 XML 包含多个子节点:

<?xml version="1.0" encoding="utf-8"?>
<testsuites duration="6376 ms">
  <testsuite>
    <testcase>
      <testid>A1</testid>
      <package>Package 1</package>
      <test>Test 1</test>
      <duration>2 ms</duration>
      <failures>0</failures>
      <pass>4</pass>
      <testparts>
        <testpart>
          <time>2020-08-23-17-03-24</time>
          <status>Test passed</status>
          <test>Assertion 1</test>
        </testpart>
        <testpart>
          <time>2020-08-23-17-03-24</time>
          <status>Test passed</status>
          <test>Assertion 2</test>
        </testpart>
        <testpart>
          <time>2020-08-23-17-03-24</time>
          <status>Test passed</status>
          <test>Assertion 3</test>
        </testpart>
      </testparts>
    </testcase>
  </testsuite>
  .......

XSLT 文件是:

<?xml version="1.0" encoding="utf-8"?> 
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    ...Some styles and scripts
  </head>
  <body>
    <div>
        <xsl:for-each select="testsuites/testsuite/testcase">
            <span class="column1"><xsl:value-of select="duration"/></span>
            <span class="PackageStatus"><xsl:value-of select="package"/></span>
            <span class="Function"><xsl:value-of select="test"/></span>
            <span class="Message" name="ID0AFH0IHId"><xsl:value-of select="failures"/></span>
            <span class="Message" name="ID0AFH0IHId"><xsl:value-of select="pass"/></span>
            <span class="Message" name="ID0AFH0IHId"><xsl:value-of select="pass"/>Show Assertions</span>
            
            <div>
                <xsl:for-each select="testsuites/testsuite/testcase/testparts/testpart">
                  <span class="column1"><xsl:value-of select="time"/></span>
                  <span class="passed"><xsl:value-of select="status"/></span>
                  <span class="Function"><xsl:value-of select="test"/></span>
              </xsl:for-each>
            </div>
        </xsl:for-each>
    </div>
</body>
</html>

您可以看到有多个测试用例,并且在其下方,testparts 有多个 testpart 元素。 现在第一个 foreach 正在按预期工作,但内部的没有工作

【问题讨论】:

我认为那是因为你有内部 for-each 的选择的绝对路径,尝试改为仅 select="testparts/testpart" Bingo..thanks @nordenvall,现在解决了,非常感谢 【参考方案1】:

这更像是一个通用的 XML 问题,但要获得比我上面的评论更完整的答案,我参考了 XSLT documentation regarding focus,上面写着:

[定义:上下文项是当前正在处理的项。 一个项目(参见 [XDM 3.0])要么是一个原子值(例如一个整数, 日期或字符串)、节点或函数项。随时变化 xsl:apply-templates 和 xsl:for-each 等指令用于 处理一系列项目;这样一个序列中的每个项目都成为 正在处理该项目时的上下文项目。] 上下文项目是 由 XPath 表达式返回。 (点)。

因此,当您输入第一个 for-each 时,上下文已更改,您需要应用与该上下文相关的进一步选择,对于您的示例,将绝对路径更改为内部选择的相对路径就足够了循环:

<xsl:for-each select="testparts/testpart">

【讨论】:

以上是关于XSLT 1.0 - 用 HTML 包装的多个子节点模板的主要内容,如果未能解决你的问题,请参考以下文章

XSLT教程

XSLT 1.0 将同一级别的多个相同节点以不同的值分组

XSLT 将来自多个节点的属性连接成单个值

如何使用 XPATH for XML 获取子节点数

有没有一种优雅的方法可以用 XSLT 添加多个 HTML 类?

选择属性的所有值并使用 XSLT 1.0 作为列表返回