0

これであなたの指導が必要です。

非正規化されたXMLから親子XMLを作成しようとしています。

から:

<Parent>Parent1</Parent>
<Child>Child1</Child>
<Parent>Parent2</Parent>
<Child>Child1</Child>
<Child>Child2</Child>
<Parent>Parent3</Parent>
<Child>Child1</Child>

に:

<Parent>
<ParentValue>Parent1</ParentValue>
<Child>
    <ChildValue>Child1</ChildValue>
</Child>
</Parent>
<Parent>
<ParentValue>Parent2</ParentValue>
<Child>
    <ChildValue>Child1</ChildValue>
</Child>
<Child>
    <ChildValue>Child2</ChildValue>
</Child>
</Parent>
<Parent>
<ParentValue>Parent3</ParentValue>
<Child>
    <ChildValue>Child1</ChildValue>
</Child>
</Parent>

問題は、各親要素の間にすべての子要素を取得するというロジックを理解できないことです。

どんな助けでも大歓迎です。

これを調べてくれてありがとう。

4

1 に答える 1

4

XSLT1.0 では、キーを使用してこれを実現できました。要素を最初の先行する要素で効果的にグループ化するため、次のキーを定義できます。

<xsl:key name="child" match="Child" use="generate-id(preceding-sibling::Parent[1])"/>

次に、親要素に一致するテンプレート内で、関連するすべての要素を次のように取得できます。

<xsl:apply-templates select="key('child', 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="child" match="Child" use="generate-id(preceding-sibling::Parent[1])"/>

   <xsl:template match="Family">
      <Family>
         <xsl:apply-templates select="Parent"/>
      </Family>
   </xsl:template>

   <xsl:template match="Parent">
      <Parent>
         <ParentValue>
            <xsl:value-of select="."/>
         </ParentValue>
         <xsl:apply-templates select="key('child', generate-id())"/>
      </Parent>
   </xsl:template>

   <xsl:template match="Child">
      <Child>
         <ChildValue>
            <xsl:value-of select="."/>
         </ChildValue>
      </Child>
   </xsl:template>
</xsl:stylesheet>

XML に適用すると、以下が出力されます。

<Family>
   <Parent>
      <ParentValue>Parent1</ParentValue>
      <Child>
         <ChildValue>Child1</ChildValue>
      </Child>
   </Parent>
   <Parent>
      <ParentValue>Parent2</ParentValue>
      <Child>
         <ChildValue>Child1</ChildValue>
      </Child>
      <Child>
         <ChildValue>Child2</ChildValue>
      </Child>
   </Parent>
   <Parent>
      <ParentValue>Parent3</ParentValue>
      <Child>
         <ChildValue>Child1</ChildValue>
      </Child>
   </Parent>
</Family>

XSLT2.0 では、 xsl:for-each-groupを利用できます。あなたの場合、要素から始まる要素をグループ化する必要があります。

<xsl:for-each-group select="*" group-starting-with="Parent">

次に、子要素を選択するには、 current-group関数を使用できます。

<xsl:apply-templates select="current-group()[position() &gt; 1]" />

2.0 の完全な XSLT は次のとおりです。

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

   <xsl:template match="/Family">
     <Family>
      <xsl:for-each-group select="*" group-starting-with="Parent">
         <Parent>
            <ParentValue>
               <xsl:value-of select="."/>
            </ParentValue>
            <xsl:apply-templates select="current-group()[position() &gt; 1]" />
         </Parent>
      </xsl:for-each-group>
     </Family>
   </xsl:template>

   <xsl:template match="Child">
      <Child>
         <ChildValue>
            <xsl:value-of select="."/>
         </ChildValue>
      </Child>
   </xsl:template>
</xsl:stylesheet>

これも同じ結果を出力するはずです。

于 2013-02-14T21:16:38.733 に答える