2017-05-09 4 views
0

재귀 적으로 템플릿을 적용하는 데 문제가 있습니다. 단순한 XSL 변환으로 몇 번 일했지만 깊은 지식이 없다고 말하고 싶습니다. xsl 변형 후 재귀 적으로 적용 템플릿

나는이 방법으로 클래스를 나타내고

<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> 

속성과 내가 모두 자체와 그 기본 클래스의 모든 속성과 메소드와 클래스를 포함하는 XML을 취득하고자하는 다음과 같은 XML OO 상속과 동일한 방식으로 작동합니다.

나는

<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을 쓴 다음 XML을 구하는 좋아하지만, 단지 클래스 상속 한 수준 일 것이다. 나는 클래스가 가지고 상속의 최대 레벨로 위의 변환을 여러 번 적용하는 경우 물론

<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> 

는, 내가 (거의) 원하는 결과를 얻을 수 있지만, 내 목표는 단지 ​​하나의 변환에서 그것을 얻을 수 있습니다 .

모든 가이드는 크게 감사하겠습니다. 미리 감사드립니다.

+1

첫 번째 문제는 하나의 질문에 충분합니다. 다른 질문을 별도로 게시하십시오. –

+0

질문을 편집하여 편집하고 다른 게시물에 두 번째 질문을 게시합니다. – hmb

답변

0

가 여기에 귀하의 첫 번째 문제에 접근하는 방법은 다음과 같습니다 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> 

이 입력 예에 적용

XSLT를, 그 결과는 다음과 같습니다

<?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> 

내가 읽어 보지 않았 당신의 두 번째 질문.

+0

감사합니다. Michael. 질문의 첫 번째 부분에서는 훌륭하게 작동하지만 두 번째 부분에서는 외부 XML에서 데이터를 가져오고 있습니다. 알고있는 한이 경우 키를 사용하면 작동하지 않습니다. – hmb

+0

키를 사용하지 않고 이러한 종류의 변형을 수행하는 다른 방법이 있습니까? – hmb

+0

[가져 오기] (https://www.w3.org/TR/xslt/#import)라는 용어는 이미 다른 스타일 시트 **를 가져 오기 위해 XSLT에서 사용되었습니다. 다른 XML 문서를 참조하기 만하면 데이터를 "가져 오는"것이 아닙니다. 그리고 다른 문서에서 키를 사용할 수 있습니다. XSLT 1.0에서 해당 문서의 컨텍스트를 먼저 전환해야합니다. 예를 들어' in 위의 스타일 시트는 효율적이지는 않지만 동일한 것을 수행합니다. –