1

私はxsltを初めて使用します。スタイルシートを書くのを手伝ってください.私はこのような入力xmlを持っています

入力 XML:

    <elements>
     <e1>
       <pid>1</pid>
       <cid>2</cid>
     </e1>

     <e1>
      <pid>1</pid>
      <cid>3</cid>
     </e1>

     <e1>
      <pid>2</pid>
      <cid>4</cid>
    </e1>
    </elements>

必要な XML:

    <tree>
      <unit id="1">
        <unit id="2">
           <unit id="4">
             <data></data>
           </unit>
           <data></data>
        </unit>

        <unit id="3">
           <data></data>
        </unit>

        <data></data>

      </unit>
    </tree>

これは本当に簡単だと思いますが、これを行う方法に関する情報を見つけるのに苦労しています。私の XSLT の知識はあまりありません。

4

2 に答える 2

2

XSLT がその入力から最上位 ID が 1 であることをどのように判断するのか、100% 確信が持てません (pid対応するcid値がない唯一の値なのか、それとも常に 1 なのか?)。それにもかかわらず、これは仕事をするはずです:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:key name="kItemsByC" match="e1" use="cid" />
  <xsl:key name="kItemsByP" match="e1" use="pid" />

  <xsl:template match="/">
    <tree>
      <xsl:call-template name="Unit">
        <!-- This will be the value of the <pid> that has no <cid> references to
             it (assuming there is only one top-level <pid>) -->
        <xsl:with-param name="id" 
                        select="string(/elements/e1/pid[not(key('kItemsByC', .))])" />
      </xsl:call-template>
    </tree>
  </xsl:template>

  <xsl:template match="e1" name="Unit">
    <xsl:param name="id" select="cid" />

    <unit id="{$id}">
      <xsl:apply-templates select="key('kItemsByP', $id)" />
      <data />
    </unit>
  </xsl:template>
</xsl:stylesheet>

これをサンプル入力で実行すると、次のようになります。

<tree>
  <unit id="1">
    <unit id="2">
      <unit id="4">
        <data />
      </unit>
      <data />
    </unit>
    <unit id="3">
      <data />
    </unit>
    <data />
  </unit>
</tree>

注:上記の XSLT には、最上位 ID を動的に見つけようとするロジックがあります。最上位ユニットの ID が常に 1 であると想定できる場合、1 つのキーと上記の XSLT の (やや) 複雑な式は省略できます。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:key name="kItemsByP" match="e1" use="pid" />

  <xsl:template match="/">
    <tree>
      <xsl:call-template name="Unit">
        <xsl:with-param name="id" select="1" />
      </xsl:call-template>
    </tree>
  </xsl:template>

  <xsl:template match="e1" name="Unit">
    <xsl:param name="id" select="cid" />

    <unit id="{$id}">
      <xsl:apply-templates select="key('kItemsByP', $id)" />
      <data />
    </unit>
  </xsl:template>
</xsl:stylesheet>

サンプル入力で実行すると、要求された出力も生成されます。

于 2013-02-09T21:28:38.597 に答える
0

ああ、JLRishe を読んだ後、「pid」は「親 ID」を意味し、「cid」は「子 ID」を意味し、e1 は親子関係を表します。素晴らしい探偵の仕事、私は自分でそれを解決したことはなかった.

基本的なモデルは、親要素に配置されたときに、その子要素にテンプレートを適用するというものです。これは、親子関係が XML 階層を使用して表される場合と同様に、主キー/外部キーによって表される場合にも当てはまります。したがって、本質は次のとおりです。

<xsl:template match="e1">
  <unit id="{pid}">
    <xsl:apply-templates select="//e1[pid=current()/cid]"/>
    <data/>
  </unit>
</xsl:template>

キーを使用して最適化を追加したことを除いて、これは本質的に JLRishe のソリューションです。

于 2013-02-10T00:06:21.093 に答える