0

以下の入力 xml には、subroot タグの下に多くの「a」要素があります。キー ID を持ち、「ab」で始まらない「a」グループは、「ab」で始まる先行する「a」要素 (keyid 要素) の下に配置する必要があります。出力には、新しいタグ「subdetail」が含まれます。これが私の望ましい出力です。サブグループがない場合、subdetail 要素は出力に含まれません。入力xml

<Root>
  <subroot>
    <a>
      <keyid>ab123456</keyid>
      <detail>hi</detail>
    </a>
    <a>
      <keyid>09876</keyid>
      <detail>undermain1</detail>
    </a>
    <a>
      <keyid>087564</keyid>
      <detail>undermain2</detail>
    </a>
    <a>
      <keyid>ab4567</keyid>
      <detail>hi</detail>
    </a>
    <a>
      <keyid>056432</keyid>
      <detail>undermain1</detail>
    </a>
  </subroot>
</Root>

希望の出力

<Root>
  <subroot>
    <a>
      <keyid>ab123456</keyid>
      <detail>hi</detail>
      <subdetail>
        <detail>undermain1</detail>
      </subdetail>
      <subdetail>
        <detail>undermain2</detail>
      </subdetail>
    </a>
    <a>
      <keyid>ab4567</keyid>
      <detail>hi</detail>
      <subdetail>
        <detail>undermain1</detail>
      </subdetail>
    </a>
  </subroot>
</Root>
4

1 に答える 1

1

これは、「ab」キーを持つ最も前の要素によって要素グループ化するキーを作成することによって実現できます

<xsl:key 
   name="a" 
   match="a[not(starts-with(keyid, 'ab'))]" 
   use="generate-id(preceding-sibling::a[starts-with(keyid, 'ab')][1])" />

次に、a要素を「ab」キーと一致させると、次のように他のa要素を取得できます

<xsl:apply-templates select="key('a', generate-id())" />

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="a" match="a[not(starts-with(keyid, 'ab'))]" use="generate-id(preceding-sibling::a[starts-with(keyid, 'ab')][1])" />

   <xsl:template match="subroot">
      <xsl:apply-templates select="a[starts-with(keyid, 'ab')]" />
   </xsl:template>

   <xsl:template match="a[starts-with(keyid, 'ab')]">
      <a>
         <xsl:apply-templates select="@*|node()" />
         <xsl:apply-templates select="key('a', generate-id())" />
      </a>
   </xsl:template>

   <xsl:template match="a">
      <subdetail>
         <xsl:copy-of select="detail" />
      </subdetail>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

サンプル XML に適用すると、次のように出力されます。

<Root>
   <a>
      <keyid>ab123456</keyid>
      <detail>hi</detail>
      <subdetail>
         <detail>undermain1</detail>
      </subdetail>
      <subdetail>
         <detail>undermain2</detail>
      </subdetail>
   </a>
   <a>
      <keyid>ab4567</keyid>
      <detail>hi</detail>
      <subdetail>
         <detail>undermain1</detail>
      </subdetail>
   </a>
</Root>
于 2012-08-01T07:24:18.623 に答える