0

私は持っている:

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 で「グループ化」したいと考えています。

各グループはStartで始まり、 Endで終わる必要があります 。 私の最初のアイデアは、このソリューションでそれを行うことでした:

これは:

<xsl:for-each select="/TestCases/TestCase/TestCaseElement[../TestCaseElement[Name='Step-Start'] << . and . >> ../TestCaseElement[Name='Step-End']]">

しかし、キーおよび/または生成IDでグループ化し、フォローシブリング先行シブリングを使用する必要があると思います

私の希望する出力: 開始要素と終了要素で正確にカバーされているすべてのコンテンツが必要です。

これは、「グループ化」したいTestCaseElementの下の 1 つの層であるため、名前Startを求める方法が明確ではありませんか?

いつか利用できる場合、各グループにアクセスするにはどうすればよいですか。

4

2 に答える 2

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>
于 2012-08-01T16:04:08.517 に答える
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() のメンバーごとに再計算する必要がないようにします。

于 2012-08-02T12:00:22.163 に答える