XSLT分组特定兄弟姐妹

时间:2016-06-22 18:55:13

标签: xml xslt xslt-1.0 xslt-grouping

我现在正在使用XSLT 1.0,而且我无法正确分组。我的xml无法更改,它看起来像:

<Analysis>
  <comment>Test 1</comment>
  <Action>
    <Result>Passed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <comment>Start 2nd Phase</comment>
  <Action>
    <Result>Failed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <comment>Test 2</comment>
  <Action>
    <Result>Failed</Result>
  </Action>
  <Action>
    <Result>Failed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <comment>Start 2nd Phase</comment>
  <Action>
    <Result>Failed</Result>
  </Action>
  <comment>Start 3rd Phase</comment>
  <Action>
    <Result>Failed</Result>
  </Action>
  <comment>Test 3</comment>
  <Action>
    <Result>Passed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <comment>Test 4</comment>
  <Action>
    <Result>Failed</Result>
  </Action>
  <Action>
    <Result>Failed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
  <comment>Start 2nd Phase</comment>
  <Action>
    <Result>Failed</Result>
  </Action>
  <Action>
    <Result>Passed</Result>
  </Action>
</Analysis>

我目前拥有的代码如果在测试下面发现失败,将打印失败,但它只执行一次。但是,现在它在每个评论的下面,而不是每个评论都有“测试”。

<xsl:key name="actions" match="Action" use="generate-id(preceding-sibling::comment[1])" />

<xsl:template match="/Analysis">
    <table>
        <xsl:for-each select="comment">
            <tr>
                <td>
                    <xsl:if test="starts-with(text(),'Test')">
                        <xsl:value-of select="."/>
                    </xsl:if>
                </td>
            </tr>   
            <xsl:if test="key('actions', generate-id())[Result='Failed']">
                <tr>
                    <td>Failed</td>
                </tr>
            </xsl:if>
        </xsl:for-each>
    </table>
</xsl:template>

有没有办法让“preceding-sibling :: comment [1]”仅适用于以“Test”开头或包含“Test”的评论?有许多不重要的评论散布在重要信息中。与上面的示例一样,我希望看到一个类似

的输出
Test 1
Failed
Test 2
Failed
Test 3
Test 4
Failed

但是,根据我目前的代码,我得到了

Test 1  
Failed 
Test 2 
Failed 
Failed 
Failed 
Test 3 
Test 4 
Failed 
Failed 

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

您应该能够将谓词直接添加到xsl:key ...

<xsl:key 
  name="actions" 
  match="Action" 
  use="generate-id(preceding-sibling::comment[starts-with(normalize-space(),'Test')][1])" 
/>

我还删除xsl:if并将测试放在xsl:for-each上。这样,您就不会为要忽略的评论获取空行。

完整示例......

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key 
    name="actions" 
    match="Action" 
    use="generate-id(preceding-sibling::comment[starts-with(normalize-space(),'Test')][1])" 
  />

  <xsl:template match="/Analysis">
    <table>
      <xsl:for-each select="comment[starts-with(normalize-space(),'Test')]">
        <tr>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
        <xsl:if test="key('actions', generate-id())[Result='Failed']">
          <tr>
            <td>Failed</td>
          </tr>
        </xsl:if>
      </xsl:for-each>
    </table>
  </xsl:template>

</xsl:stylesheet>