XSLT 对特定兄弟姐妹进行分组
XSLT Grouping Specific Siblings
我现在正在使用 XSLT 1.0,我在分组时遇到问题 correctly.My 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>
如果在测试中发现失败,我目前拥有的代码将打印失败,但它只会打印一次。但是,现在它会在每个评论下方执行此操作,而不是每个包含 "Test" 的评论。
<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
如有任何帮助,我们将不胜感激。
您应该能够将谓词直接添加到 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>
我现在正在使用 XSLT 1.0,我在分组时遇到问题 correctly.My 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>
如果在测试中发现失败,我目前拥有的代码将打印失败,但它只会打印一次。但是,现在它会在每个评论下方执行此操作,而不是每个包含 "Test" 的评论。
<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
如有任何帮助,我们将不胜感激。
您应该能够将谓词直接添加到 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>