我有:
XML
<TestCases>
<TestCase>
<TestCaseElement>
<Name><![CDATA[Start]]></Name>
<Role><![CDATA[TESTSTEP]]></Role>
</TestCaseElement>
<TestCaseElement>
<Name><![CDATA[Content]]></Name>
<Role><![CDATA[TESTSTEP]]></Role>
<Code>
<Line><![CDATA[some Content]></Line>
<Line><![CDATA[some Content]></Line>
</Code>
</TestCaseElement>
<TestCaseElement>
<Name><![CDATA[End]]></Name>
<Role><![CDATA[TESTSTEP]]></Role>
</TestCaseElement>
**n of these Start-Content-Stop Triplets are in the XML Document**
</TestCase>
</TestCases>
我想用XSLT“分组”这个元素。
每个小组应以开始开头,并以结束结尾 我的第一个想法是使用此解决方案:stackoverflow combining xslt issue
这将是:
<xsl:for-each select="/TestCases/TestCase/TestCaseElement[../TestCaseElement[Name='Step-Start'] << . and . >> ../TestCaseElement[Name='Step-End']]">
但我认为我应该使用 键 和/或 generate-id 进行分组并使用 以下兄弟 和 前兄弟
我想要的输出:我想拥有开始和结束元素精确覆盖的所有内容。
目前尚不清楚如何要求名称开始,因为这是 TestCaseElement 下的一个层,我想要“分组”?
如果有一天可以访问每个组,我该如何访问它们。
答案 0 :(得分:0)
这些方面的东西:
<xsl:template match="TestCase">
<xsl:for-each-group select="TestCaseElement" group-starting-with="*[Name='Start']">
<group>
<xsl:apply-templates select="current-group()"/>
</group>
</xsl:for-each-group>
</xsl:template>
答案 1 :(得分:0)
此XSLT 2.0样式表......
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsl xs">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="TestCase">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:for-each-group select="TestCaseElement" group-starting-with="*[Name='Start']">
<xsl:apply-templates select="current-group()
[not(. >> current-group()/self::*[Name='End'])]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
...将采用此输入文档,稍微调整以适应您的示例输入,并进行扩展以增加测试覆盖范围......
<TestCases>
<TestCase>
<TestCaseElement>
<Name>Start</Name>
<Role>TESTSTEP 1</Role>
</TestCaseElement>
<TestCaseElement>
<Name>Content 1</Name>
<Role>TESTSTEP</Role>
<Code>
<Line>some Content 1</Line>
<Line>some Content 1</Line>
</Code>
</TestCaseElement>
<TestCaseElement>
<Name>End</Name>
<Role>TESTSTEP 1</Role>
</TestCaseElement>
<TestCaseElement>
This content is dropped because it is
not between a Start and End TestCaseElement.
</TestCaseElement>
<TestCaseElement>
<Name>Start</Name>
<Role>TESTSTEP 2</Role>
</TestCaseElement>
<TestCaseElement>
<Name>Content 2</Name>
<Role>TESTSTEP</Role>
<Code>
<Line>some Content 2</Line>
<Line>some Content 2</Line>
</Code>
</TestCaseElement>
<TestCaseElement>
<Name>End</Name>
<Role>TESTSTEP 2</Role>
</TestCaseElement>
</TestCase>
</TestCases>
...并根据规定的要求产生此输出......
<TestCases>
<TestCase>
<TestCaseElement>
<Name>Start</Name>
<Role>TESTSTEP 1</Role>
</TestCaseElement>
<TestCaseElement>
<Name>Content 1</Name>
<Role>TESTSTEP</Role>
<Code>
<Line>some Content 1</Line>
<Line>some Content 1</Line>
</Code>
</TestCaseElement>
<TestCaseElement>
<Name>End</Name>
<Role>TESTSTEP 1</Role>
</TestCaseElement>
<TestCaseElement>
<Name>Start</Name>
<Role>TESTSTEP 2</Role>
</TestCaseElement>
<TestCaseElement>
<Name>Content 2</Name>
<Role>TESTSTEP</Role>
<Code>
<Line>some Content 2</Line>
<Line>some Content 2</Line>
</Code>
</TestCaseElement>
<TestCaseElement>
<Name>End</Name>
<Role>TESTSTEP 2</Role>
</TestCaseElement>
</TestCase>
</TestCases>
请注意,仅保留由划分的Start和End限定的TestCaseElement元素。此分组之外的其他节点将被删除。通过输入变量也可以获得一些效率......
current-group()/self::*[Name='End']
...这样就不需要为current-group()的每个成员重新计算这个表达式。