2013-08-27 73 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