2017-05-09 11 views
0

再帰的にテンプレートを適用する際に問題が発生しています。単純なXSL変換で数回働いたが、私はそれらの深い知識は持っていないと言いたい。 xsl変形後に再帰的にテンプレートを適用する

I有し方法でクラスを表し、

<classes> 
    <class name="A" author="Mr.X" > 
     <attribute name="i_" type="integer" visibility="protected" /> 
     <attribute name="f_" type="float" visibility="private" /> 
     <attribute name="c_" type="char" visibility="private" /> 
     <method name="foo" return="integer" visibility="public" > 
      <param name="a" type="integer" /> 
      <param name="b" type="integer" /> 
     </method> 
    </class> 

    <class name="B" author="Mr.Y" > 
     <attribute name="s_" type="string" visibility="protected" /> 
     <method name="bar" visibility="public" /> 
    </class> 

    <class name="CA" author="Mr.Z" base="A" > 
     <attribute name="d_" type="double" visibility="protected" /> 
    </class> 

    <class name="CB" author="Mr.Z" base="B" /> 

    <class name="DCA" author="Mr.X" base="CA" > 
     <attribute name="s_" type="string" visibility="protected" /> 
    </class> 
</classes> 

属性及びIは、両方自体からその基底クラスからすべての属性およびメソッドを有するクラスを含むXMLを取得したい次のXML OO継承と同じように動作します。

私は、次のXSLを書いたが、ちょうどクラスの継承の1つのレベルで動作し、次のXML

<classes> 
    <class name="A" author="Mr.X" > 
     <attribute name="i_" type="integer" visibility="protected" /> 
     <attribute name="f_" type="float" visibility="private" /> 
     <attribute name="c_" type="char" visibility="private" /> 
     <method name="foo" return="integer" visibility="public" > 
      <param name="a" type="integer" /> 
      <param name="b" type="integer" /> 
     </method> 
    </class> 

    <class name="B" author="Mr.Y" > 
     <attribute name="s_" type="string" visibility="protected" /> 
     <method name="bar" visibility="public" /> 
    </class> 

    <class name="CA" author="Mr.Z" > 
     <attribute name="d_" type="double" visibility="protected" /> 
     <!--[begin] inherited from base class A by Mr.X--> 
     <attribute name="i_" type="integer" visibility="protected" /> 
     <attribute name="f_" type="float" visibility="private" /> 
     <attribute name="c_" type="char" visibility="private" /> 
     <method name="foo" return="integer" visibility="public" > 
      <param name="a" type="integer" /> 
      <param name="b" type="integer" /> 
     </method> 
     <!--[end] inherited from base class A--> 
    </class> 

    <class name="CB" author="Mr.Z" > 
     <!--[begin] inherited from base class B by Mr.Y--> 
     <attribute name="s_" type="string" visibility="protected" /> 
     <method name="bar" visibility="public" /> 
     <!--[end] inherited from base class B--> 
    </class> 

    <class name="DCA" author="Mr.X" > 
     <attribute name="s_" type="string" visibility="protected" /> 
     <!--[begin] inherited from base class CA by Mr.Z--> 
     <attribute name="d_" type="double" visibility="protected" /> 
     <!--[begin] inherited from base class A by Mr.X--> 
     <attribute name="i_" type="integer" visibility="protected" /> 
     <attribute name="f_" type="float" visibility="private" /> 
     <attribute name="c_" type="char" visibility="private" /> 
     <method name="foo" return="integer" visibility="public" > 
      <param name="a" type="integer" /> 
      <param name="b" type="integer" /> 
     </method> 
     <!--[end] inherited from base class A--> 
     <!--[end] inherited from base class CA--> 
    </class> 
</classes> 

を取得したいと思います。もちろん

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

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

    <xsl:template match="/classes/import"> 
     <xsl:comment>importing <xsl:value-of select="@file"/> file</xsl:comment> 
     <xsl:apply-templates select="document(@file)/classes/node()" /> 
    </xsl:template> 

    <xsl:template match="*[@base]"> 
     <xsl:variable name="bc" select="@base" /> 
     <xsl:copy> 
      <xsl:apply-templates select="@*[name(.)!='base']"/>      
      <xsl:apply-templates select="/classes/class[@name=$bc]/@*[name(.)!='name' and name(.)!='author']" /> 
      <xsl:apply-templates /> 
      <xsl:comment>[begin] inherited from base class <xsl:value-of select="$bc"/> by <xsl:value-of select="//class[@name=$bc]/@author"/></xsl:comment> 
      <xsl:apply-templates select="/classes/class[@name=$bc]/node()" /> 
      <xsl:comment>[end] inherited from base class <xsl:value-of select="$bc"/></xsl:comment> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

私はクラスが持っていることを、継承の最大レベル何度でも上記のように変換を適用する場合、I(ほぼ)所望の結果を得るが、私の目標はただ一つの変換でそれを取得することです。

ガイドがあれば幸いです。前もって感謝します。ここで

+1

あなたの最初の問題は、1つの質問で十分です。別の質問を別途投稿してください。 –

+0

私はそれを分割するために質問を編集し、私は別の投稿に2番目のものを投稿します。 – hmb

答えて

0

があなたの最初の問題アプローチする方法は次のとおりです。あなたの入力例に

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="parent" match="class" use="@name" /> 

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

<xsl:template match="class"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     <xsl:apply-templates select="key('parent', @base)" mode="inherit"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="class" mode="inherit"> 
    <xsl:comment> 
     <xsl:text>[begin] inherited from class </xsl:text> 
     <xsl:value-of select="@name"/> 
    </xsl:comment> 
    <xsl:copy-of select="attribute | method"/> 
    <xsl:apply-templates select="key('parent', @base)" mode="inherit"/> 
    <xsl:comment> 
     <xsl:text>[end] inherited from class </xsl:text> 
     <xsl:value-of select="@name"/> 
    </xsl:comment> 
</xsl:template> 

</xsl:stylesheet> 

応用し、その結果は以下のようになります。

<?xml version="1.0" encoding="UTF-8"?> 
<classes> 
    <class name="A" author="Mr.X"> 
    <attribute name="i_" type="integer" visibility="protected"/> 
    <attribute name="f_" type="float" visibility="private"/> 
    <attribute name="c_" type="char" visibility="private"/> 
    <method name="foo" return="integer" visibility="public"> 
     <param name="a" type="integer"/> 
     <param name="b" type="integer"/> 
    </method> 
    </class> 
    <class name="B" author="Mr.Y"> 
    <attribute name="s_" type="string" visibility="protected"/> 
    <method name="bar" visibility="public"/> 
    </class> 
    <class name="CA" author="Mr.Z" base="A"> 
    <attribute name="d_" type="double" visibility="protected"/> 
    <!--[begin] inherited from class A--> 
    <attribute name="i_" type="integer" visibility="protected"/> 
    <attribute name="f_" type="float" visibility="private"/> 
    <attribute name="c_" type="char" visibility="private"/> 
    <method name="foo" return="integer" visibility="public"> 
     <param name="a" type="integer"/> 
     <param name="b" type="integer"/> 
    </method> 
    <!--[end] inherited from class A--> 
    </class> 
    <class name="CB" author="Mr.Z" base="B"> 
    <!--[begin] inherited from class B--> 
    <attribute name="s_" type="string" visibility="protected"/> 
    <method name="bar" visibility="public"/> 
    <!--[end] inherited from class B--> 
    </class> 
    <class name="DCA" author="Mr.X" base="CA"> 
    <attribute name="s_" type="string" visibility="protected"/> 
    <!--[begin] inherited from class CA--> 
    <attribute name="d_" type="double" visibility="protected"/> 
    <!--[begin] inherited from class A--> 
    <attribute name="i_" type="integer" visibility="protected"/> 
    <attribute name="f_" type="float" visibility="private"/> 
    <attribute name="c_" type="char" visibility="private"/> 
    <method name="foo" return="integer" visibility="public"> 
     <param name="a" type="integer"/> 
     <param name="b" type="integer"/> 
    </method> 
    <!--[end] inherited from class A--> 
    <!--[end] inherited from class CA--> 
    </class> 
</classes> 

私はあなたを読んでいません2番目の質問。

+0

マイケルに感謝します。質問の最初の部分ではうまくいきますが、2番目の部分にあるように、外部XMLからデータをインポートしています。私が知る限り、このような状況ではキーを使用できません。 – hmb

+0

キーを使用せずにこの種の変換を行う他の方法はありますか? – hmb

+0

別の**スタイルシート**をインポートするために、[import](https://www.w3.org/TR/xslt/#import)という用語がすでにXSLTで使用されています。データを「インポート」するのではなく、別のXMLドキュメントを参照するだけです。また、別のドキュメントのキーを使用することもできます(XSLT 1.0では、最初にそのドキュメントにコンテキストを切り替えることができます)。キーの代わりに述語を使うこともできます:例えば、 '' in上記のスタイルシートは、それほど効率的ではありませんが、同じことを達成します。 –