DotNetNuke + XPath =自定义导航菜单DNNMenu HTML渲染

时间:2010-04-21 09:40:49

标签: html xml xslt xhtml dotnetnuke

我正在使用Mark Alan的Component DNN Done Right菜单开发DotNetNuke 5的皮肤,该菜单使用XSL-T将XML站点地图转换为HTML导航。

XML站点地图输出以下结构:

<Root >
  <root >
    <node id="40" text="Home" url="http://localhost/dnn/Home.aspx" enabled="1" selected="0" breadcrumb="0" first="1" last="0" only="0" depth="0" >
      <node id="58" text="Child1" url="http://localhost/dnn/Home/Child1.aspx" enabled="1" selected="0" breadcrumb="0" first="1" last="0" only="0" depth="1" >
        <keywords >Child1</keywords>
        <description >Child1</description>
        <node id="59" text="Child1 SubItem1" url="http://localhost/dnn/Home/Child1/Child1SubItem1.aspx" enabled="1" selected="0" breadcrumb="0" first="1" last="0" only="0" depth="2" >
          <keywords >Child1 SubItem1</keywords>
          <description >Child1 SubItem1</description>
        </node>
        <node id="60" text="Child1 SubItem2" url="http://localhost/dnn/Home/Child1/Child1SubItem2.aspx" enabled="1" selected="0" breadcrumb="0" first="0" last="0" only="0" depth="2" >
          <keywords >Child1 SubItem2</keywords>
          <description >Child1 SubItem2</description>
        </node>
        <node id="61" text="Child1 SubItem3" url="http://localhost/dnn/Home/Child1/Child1SubItem3.aspx" enabled="1" selected="0" breadcrumb="0" first="0" last="1" only="0" depth="2" >
          <keywords >Child1 SubItem3</keywords>
          <description >Child1 SubItem3</description>
        </node>
      </node>
      <node id="65" text="Child2" url="http://localhost/dnn/Home/Child2.aspx" enabled="1" selected="0" breadcrumb="0" first="0" last="1" only="0" depth="1" >
        <keywords >Child2</keywords>
        <description >Child2</description>
        <node id="66" text="Child2 SubItem1" url="http://localhost/dnn/Home/Child2/Child2SubItem1.aspx" enabled="1" selected="0" breadcrumb="0" first="1" last="0" only="0" depth="2" >
          <keywords >Child2 SubItem1</keywords>
          <description >Child2 SubItem1</description>
        </node>
        <node id="67" text="Child2 SubItem2" url="http://localhost/dnn/Home/Child2/Child2SubItem2.aspx" enabled="1" selected="0" breadcrumb="0" first="0" last="1" only="0" depth="2" >
          <keywords >Child2 SubItem2</keywords>
          <description >Child2 SubItem2</description>
        </node>
      </node>
    </node>
  </root>
</Root>

我的目标是仅使用UL的LI等将此XML块渲染到此HTML导航结构中。

<ul id="topnav">
  <li>
    <a href="#" class="home">Home</a><!-- Parent Node - Depth0 -->
    <div class="sub">
      <ul>
        <li><h2><a href="#">Child1</a></h2></li><!-- Parent Node 1 - Depth1 -->
        <li><a href="#">Child1 SubItem1</a></li><!-- ChildNode - Depth2 -->
        <li><a href="#">Child1 SubItem2</a></li><!-- ChildNode - Depth2 -->
        <li><a href="#">Child1 SubItem3</a></li><!-- ChildNode - Depth2 -->
      </ul>
      <ul>
        <li><h2><a href="#">Child2</a></h2></li><!-- Parent Node 2 - Depth1 -->
        <li><a href="#">Child2 SubItem1</a></li><!-- ChildNode - Depth2 -->
        <li><a href="#">Child2 SubItem2</a></li><!-- ChildNode - Depth2 -->
      </ul>
    </div>
  </li>
</ul>

任何人都可以帮助XSL编码吗?我现在刚开始使用XSL ..

1 个答案:

答案 0 :(得分:1)

我建议正确嵌套<ul>列表。逻辑上,"Child1 SubItem1"不能与“Child1”处于同一级别。这个XSLT 1.0转换:

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

  <xsl:template match="Root">
    <html>
      <body>
        <!-- render a sub-list if the <root> node -->
        <xsl:apply-templates select="root" mode="sub-list" />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="*[node]" mode="sub-list">
    <ul>
      <!-- render all list items from enabled child nodes -->
      <xsl:apply-templates select="node[@enabled=1]" mode="list-item" />
    </ul>
  </xsl:template>

  <xsl:template match="node" mode="list-item">
    <li id="menu_{@id}" class="level{@depth}">
      <a href="{@url}">
        <xsl:value-of select="@text" />
      </a>
      <!-- if there are any enabled child nodes... -->
      <xsl:if test="node[@enabled=1]">
        <!-- ...make a sub-list from the current node (.) -->
        <xsl:apply-templates select="." mode="sub-list" />
      </xsl:if>
    </li>
  </xsl:template>

</xsl:stylesheet>

产生

<html>
  <body>
    <ul>
      <li id="menu_40" class="level0">
        <a href="http://localhost/dnn/Home.aspx">Home</a>
        <ul>
          <li id="menu_58" class="level1">
            <a href="http://localhost/dnn/Home/Child1.aspx">Child1</a>
            <ul>
              <li id="menu_59" class="level2">
                <a href="http://localhost/dnn/Home/Child1/Child1SubItem1.aspx">Child1 SubItem1</a>
              </li>
              <li id="menu_60" class="level2">
                <a href="http://localhost/dnn/Home/Child1/Child1SubItem2.aspx">Child1 SubItem2</a>
              </li>
              <li id="menu_61" class="level2">
                <a href="http://localhost/dnn/Home/Child1/Child1SubItem3.aspx">Child1 SubItem3</a>
              </li>
            </ul>
          </li>
          <li id="menu_65" class="level1">
            <a href="http://localhost/dnn/Home/Child2.aspx">Child2</a>
            <ul>
              <li id="menu_66" class="level2">
                <a href="http://localhost/dnn/Home/Child2/Child2SubItem1.aspx">Child2 SubItem1</a>
              </li>
              <li id="menu_67" class="level2">
                <a href="http://localhost/dnn/Home/Child2/Child2SubItem2.aspx">Child2 SubItem2</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </body>
</html>

现在您可以使用CSS进行演示,例如每class<li>属性。


编辑由于评论中的特殊要求,这里的样式表似乎可以产生您想要的内容:

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="root">
    <ul id="topnav">
      <xsl:apply-templates select="node" mode="li" />
    </ul>
  </xsl:template>

  <xsl:template match="node" mode="li">
    <xsl:if test="@enabled=1">
      <li>
        <xsl:apply-templates select="." mode="a" />
        <!-- build sub-menu for enabled child nodes only -->
        <xsl:if test="node[@enabled=1]">
          <div class="sub">
            <xsl:apply-templates select="node" mode="ul" />
          </div>
        </xsl:if>
      </li>
    </xsl:if>
  </xsl:template>

  <xsl:template match="node" mode="ul">
    <ul>
      <!-- heading for this list -->
      <li>
        <h2><xsl:apply-templates select="." mode="a" /></h2>
      </li>
      <!-- other list elements from sub-nodes -->
      <xsl:apply-templates select="node" mode="li" />
    </ul>
  </xsl:template>

  <xsl:template match="node" mode="a">
    <a href="{@url}"><xsl:value-of select="@text" /></a>
  </xsl:template>
</xsl:stylesheet>

示例XML的输出:

<ul id="topnav">
  <li>
    <a href="http://localhost/dnn/Home.aspx">Home</a>
    <div class="sub">
      <ul>
        <li><h2><a href="http://localhost/dnn/Home/Child1.aspx">Child1</a></h2></li>
        <li><a href="http://localhost/dnn/Home/Child1/Child1SubItem1.aspx">Child1 SubItem1</a></li>
        <li><a href="http://localhost/dnn/Home/Child1/Child1SubItem2.aspx">Child1 SubItem2</a></li>
        <li><a href="http://localhost/dnn/Home/Child1/Child1SubItem3.aspx">Child1 SubItem3</a></li>
      </ul>
      <ul>
        <li><h2><a href="http://localhost/dnn/Home/Child2.aspx">Child2</a></h2></li>
        <li><a href="http://localhost/dnn/Home/Child2/Child2SubItem1.aspx">Child2 SubItem1</a></li>
        <li><a href="http://localhost/dnn/Home/Child2/Child2SubItem2.aspx">Child2 SubItem2</a></li>
      </ul>
    </div>
  </li>
</ul>