2013-08-27 78 views
0

我得在這裏頗有些挑戰...通用XSLT轉換代碼

是否有可能有一個XSL代碼,將應用到XML的任何層次,將其改造成嵌套的HTML列表?

例XML:

<Base> 
    <Parent> 
    <Child /> 
    <Child> 
     <ChildOne /> 
     <ChildOne> 
     <ChildTwo /> 
     <ChildTwo /> 
     </ChildOne> 
    </Child> 
    </Parent> 
    <Parent> 
    <Child> 
     <ChildOne> 
     <ChildTwo> 
      <ChildThree> 
      <ChildFour /> 
      </ChildThree> 
      <ChildThree/> 
     </ChildTwo> 
     </ChildOne> 
     <ChildOne/> 
     <ChildOne/> 
    </Child> 
    <Child/> 
    </Parent> 
</Base> 

期望的結果:

<ul> 
    <li>Parent1 
    <ul> 
     <li>Child</li> 
     <li>Child 
     <ul> 
     <li>ChildOne</li> 
     <li>ChildOne> 
      <ul> 
       <li>ChildTwo</li> 
       <li>ChildTwo</li> 
      </ul> 
     </li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
    <li>Parent2 
    <ul> 
     <li>Child 
     <ul> 
      <li>ChildOne 
       <ul> 
        <li>ChildTwo 
        <ul> 
        <li>ChildThree 
        <ul> 
         <li>ChildFour</li> 
        </ul> 
        </li> 
        <li>ChildThree</li> 
        </ul> 
       </li> 
      </ul> 
      </li> 
      <li>ChildOne</li> 
      <li>ChildOne</li> 
     </ul> 
     </li> 
     <li>Child</li> 
    </ul> 
    </li> 
</ul> 

所以邏輯是,如果有其他元素的元件(上EL下(抑制EL)。 ) - 被壓制的el。通過<li>name of upper el.<ul>all suppressed el.</ul></li>等獲得環繞聲。

我的觀點是,這個XSL代碼的作用不是通過元素或屬性的值或名稱,而是通過條件檢查,如果其他元素落在特定元素下。

F.E.,如果ChildThree沒有ChildFour下本身,它也只是<li>ChildThree>,而不是

<li>ChildThree 
    <ul> 
     <li>ChildFour</li> 
    </ul> 
</li> 

希望我解釋說清楚了。 :)

P.S.這是如何在瀏覽器一看,或多或少(只給視覺表現,因爲我們人類喜歡看到的東西:P)

enter image description here

+0

您的輸入XML在第一個「Parent」下有三個「Child」元素,而所需的輸出XML只有兩個帶有「Child」文本的「li」元素。這是否正確?如果是這樣,邏輯是什麼? (對於'ChildOne'元素也是同樣的問題。) –

+0

@Ben - 抱歉,我的錯誤。我現在糾正了它。輸入和輸出必須具有相同數量的元素(如現在這樣)。 :) – Syspect

回答

3

隨着樣式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="html" indent="yes"/> 

<xsl:template match="*[*]"> 
    <li> 
    <xsl:value-of select="local-name()"/> 
    <ul> 
     <xsl:apply-templates/> 
    </ul> 
    </li> 
</xsl:template> 

<xsl:template match="*[not(*)]"> 
    <li> 
    <xsl:value-of select="local-name()"/> 
    </li> 
</xsl:template> 

<xsl:template match="/*" priority="5"> 
    <ul> 
    <xsl:apply-templates/> 
    </ul> 
</xsl:template> 

</xsl:stylesheet> 

撒克遜6.5.5將輸入

<Base> 
    <Parent> 
    <Child /> 
    <Child> 
     <ChildOne /> 
     <ChildOne> 
     <ChildTwo /> 
     <ChildTwo /> 
     </ChildOne> 
    </Child> 
    </Parent> 
    <Parent> 
    <Child> 
     <ChildOne> 
     <ChildTwo> 
      <ChildThree> 
      <ChildFour /> 
      </ChildThree> 
      <ChildThree/> 
     </ChildTwo> 
     </ChildOne> 
     <ChildOne/> 
     <ChildOne/> 
    </Child> 
    <Child/> 
    </Parent> 
</Base> 

到結果

<ul> 

    <li>Parent 
     <ul> 

     <li>Child</li> 

     <li>Child 
      <ul> 

       <li>ChildOne</li> 

       <li>ChildOne 
        <ul> 

        <li>ChildTwo</li> 

        <li>ChildTwo</li> 

        </ul> 
       </li> 

      </ul> 
     </li> 

     </ul> 
    </li> 

    <li>Parent 
     <ul> 

     <li>Child 
      <ul> 

       <li>ChildOne 
        <ul> 

        <li>ChildTwo 
         <ul> 

          <li>ChildThree 
           <ul> 

           <li>ChildFour</li> 

           </ul> 
          </li> 

          <li>ChildThree</li> 

         </ul> 
        </li> 

        </ul> 
       </li> 

       <li>ChildOne</li> 

       <li>ChildOne</li> 

      </ul> 
     </li> 

     <li>Child</li> 

     </ul> 
    </li> 

</ul> 
1

這個XSL樣式表讓你想要你。

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <!-- Match the Base element, with high priority to avoid matching the more 
     specific template further down, that matches *[*] --> 
    <xsl:template match="Base" priority="10"> 
    <ul> 
     <xsl:apply-templates/> 
    </ul> 
    </xsl:template> 

    <!-- Match the Parent element, with high priority to avoid matching the more 
     specific template further down, that matches *[*] --> 
    <xsl:template match="Parent" priority="10"> 
    <li> 
     <!-- Output a Parent element and append it with its position amongst 
      all Parent elements at this level. --> 
     <xsl:text>Parent</xsl:text> 
     <xsl:value-of select="count(preceding-sibling::Parent) + 1"/> 
     <xsl:apply-templates/> 
    </li> 
    </xsl:template> 

    <!-- Match those elements that have children. --> 
    <xsl:template match="*[*]"> 
    <li> 
     <xsl:value-of select="local-name(.)"/> 
     <ul> 
     <xsl:apply-templates/> 
     </ul> 
    </li> 
    </xsl:template> 

    <!-- Match the remaining elements (without children) --> 
    <xsl:template match="*"> 
    <li> 
     <xsl:value-of select="local-name(.)"/> 
    </li> 
    </xsl:template> 
</xsl:stylesheet> 

你可以看到它在行動here