【问题标题】:XSLT : Select only the last rowXSLT:只选择最后一行
【发布时间】:2015-07-15 12:49:28
【问题描述】:

我想选择并显示特定的行。让我先给你看看我的 xml 文件:

    <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="TestLogTest.xsl" type="text/xsl"?>
<TestLog>
    <TestLogItem id="0">
        <Message>Zero</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="1">
        <Message>One</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="2">
        <Message>Two</Message>
        <TypeDescription>Error</TypeDescription>
    </TestLogItem>
    <TestLogItem id="3">
        <Message>Three</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="4">
        <Message>******** TestCase PA-343 is finished *********</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="5">
        <Message>Five</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="6">
        <Message>Six</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="7">
        <Message>******** TestCase PA-450 is finished *********</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
</TestLog>

步骤是测试用例的一部分,这意味着一个测试用例包含多个步骤,但步骤和测试用例是同级的。所以首先我用这个 xsl 文件在 xml 文件中下订单:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="k" match="TestLogItem[string(Message)]" use="following-sibling::TestLogItem[contains(Message, 'TestCase')][1]/@id"/>
    <xsl:template match="/TestLog">
        <table border="2">
            <th>Step</th> 
            <th>Test</th>
            <th>Result</th> 
            <xsl:for-each select="TestLogItem">
                <xsl:variable name="bingo" select="substring(Message, 19, 7)"/>
                <xsl:variable name="position" select="@id"/>
                <xsl:for-each select="key('k',@id)"> 
                    <tr>
                        <xsl:choose>
                            <xsl:when test="contains(TypeDescription, 'Error')">
                                <td bgcolor="#FF0000"><xsl:value-of select="@id"/></td>  
                                <td bgcolor="#FF0000"><xsl:value-of select="$bingo"/></td>
                                <td bgcolor="#FF0000"> Error </td>
                            </xsl:when>
                            <xsl:otherwise>
                                <td><xsl:value-of select="@id"/></td> 
                                <td><xsl:value-of select="$bingo"/></td>
                                <td> OK </td>
                            </xsl:otherwise>
                        </xsl:choose>
                    </tr>
                </xsl:for-each> 
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

这给了我这个 xml:

<?xml version="1.0" encoding="UTF-8"?>
<table border="2">
   <th>Step</th>
   <th>Test</th>
   <th>Result</th>
   <tr>
      <td>0</td>
      <td>PA-343</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>1</td>
      <td>PA-343</td>
      <td>OK</td>
   </tr>
   <tr>
      <td bgcolor="#FF0000">2</td>
      <td bgcolor="#FF0000">PA-343</td>
      <td bgcolor="#FF0000">Error</td>
   </tr>
   <tr>
      <td>3</td>
      <td>PA-343</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>4</td>
      <td>PA-450</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>5</td>
      <td>PA-450</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>6</td>
      <td>PA-450</td>
      <td>OK</td>
   </tr>
</table>

现在我只想选择每个 TestCase 的最后一步(这里是步骤 3 和 6)并显示是否有错误:

<table>
 <tr>
  <td>PA-343</td>
  <td>Error</td>
 </tr>
 <tr>
  <td>PA-450</td>
  <td>OK</td>
 </tr>
</table>

但问题是我正在使用带有密钥的 xsl:for-each 并且我不知道我是否仍然需要在 xsl:for-each 节点中工作,或者我是否必须考虑没有的解决方案钥匙。

感谢您的回答

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    如果您只想选择每个测试用例的“最后一步”,请将第一个 xsl:for-each 更改为包含标识此类步骤的条件:

    <xsl:for-each select="TestLogItem[contains(Message, 'TestCase')]">
    

    然后,要检查该步骤是否发生任何错误,不要使用内部xsl:for-each,而是使用xsl:choose 中的键来检查是否有任何步骤有错误

    <xsl:when test="key('k',@id)[contains(TypeDescription, 'Error')]">
    

    试试这个 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:key name="k" match="TestLogItem[string(Message)]" use="following-sibling::TestLogItem[contains(Message, 'TestCase')][1]/@id"/>
        <xsl:template match="/TestLog">
            <table border="2">
                <th>Step</th> 
                <th>Test</th>
                <th>Result</th> 
                <xsl:for-each select="TestLogItem[contains(Message, 'TestCase')]">
                    <xsl:variable name="bingo" select="substring(Message, 19, 7)"/>
                    <tr>
                        <xsl:choose>
                            <xsl:when test="key('k',@id)[contains(TypeDescription, 'Error')]">
                                <td bgcolor="#FF0000"><xsl:value-of select="$bingo"/></td>
                                <td bgcolor="#FF0000"> Error </td>
                            </xsl:when>
                            <xsl:otherwise>
                                <td><xsl:value-of select="$bingo"/></td>
                                <td> OK </td>
                            </xsl:otherwise>
                        </xsl:choose>
                    </tr>
                </xsl:for-each>
            </table>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 太完美了!我不知道是否可以将密钥放入 xsl:choose 非常感谢您快速而完美的回答!
    • 是否也可以显示“错误”消息但仍显示最后一步?
    • 是的,你可以这样做&lt;xsl:value-of select="key('k',@id)[contains(TypeDescription, 'Error')]/Message" /&gt;
    • 您可以使用xsl:for-each 代替...... &lt;xsl:for-each select="key('k',@id)[contains(TypeDescription, 'Error')]" &gt;&lt;xsl:value-of select="Message" /&gt;&lt;/xsl:for-each&gt;
    • 完美,再次感谢!我(再次)不是很远,但一如既往,细节让我抓狂
    猜你喜欢
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2015-01-23
    相关资源
    最近更新 更多