需要帮助来比较xsl中的两组节点

时间:2011-12-04 12:20:57

标签: xml templates xslt foreach

这是我的xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="ran.xsl"?>
    <Authentication isLogged="1" uid="40">
        <GetUserMenu>
            <MenuList>
                <row MenuID="1" MenuTitle="menu1"/>
                <row MenuID="2" MenuTitle="menu2"/>
                <row MenuID="3" MenuTitle="menu3"/>
                <row MenuID="4" MenuTitle="menu4"/>
            </MenuList>

            <FunctionList>
                <row FunctionID="1" FunctionTitle="submenu1" MenuID="1" WorkflowName="ImportDataWithoutFile" Order="1"/>
                <row FunctionID="2" FunctionTitle="submenu2" MenuID="1" WorkflowName="ImportDataFromFile" Order="2"/>
                <row FunctionID="2" FunctionTitle="submenu2" MenuID="3" WorkflowName="ImportDataFromFile" Order="2"/>
            </FunctionList>
        </GetUserMenu>
    </Authentication>

Html输出应该是这样的:

<div id="menu">
    <div>menu1
         <div class="subMenu">
             <div>submenu1
             </div>
             <div>submenu2
             </div>
         </div>
    </div>
    <div>menu2
         <div class="subMenu">
         </div>
    </div>
    <div>menu3
         <div class="subMenu">
             <div>submenu3
             </div>
         </div>
    </div>
    <div>menu4
         <div class="subMenu">
         </div>
    </div>
</div>

和xsl:

<xsl:template match="//Authentication/GetUserMenu">
        <div>
            <xsl:for-each select="//MenuList/row">
                <div><xsl:value-of select="@MenuID"/></div>
                tu
                <xsl:for-each select="//FunctionList/row[">
                    <div><xsl:value-of select="@MenuID"/></div>
                </xsl:for-each>
                tu
            </xsl:for-each>
        </div>
    </xsl:template>

我想让我的xsl这样做:

  1. 在外部for-each周期中,xsl读取<row>的{​​{1}}的MenuId属性的值。
  2. 然后在内部循环中 - 每个我的xsl将该值与<MenuList>的{​​{1}}的{​​{1}}的MenuAttribute的每个值进行比较
  3. 然后我的xsl读取<row>的{​​{1}}的{​​{1}}的MenuId属性的值,并重复第二步 通过这样做,我将能够在相应的按钮下面制作html菜单按钮和子菜单按钮。菜单和子菜单按钮之间的连接由MenuId属性
  4. 识别

    在正常的编程语言中,我想要做的事情(使用xsl)看起来像这样:

    <FunctionList>

    有人可以提出任何建议或修改我的代码以解决我的问题吗?我将不胜感激。

2 个答案:

答案 0 :(得分:0)

我认为你想使用xsl:keykey函数,如下所示:

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

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

  <xsl:key name="k1" match="FunctionList/row" use="@MenuID"/>

  <xsl:template match="/">
    <xsl:apply-templates select="Authentication/GetUserMenu"/>
  </xsl:template>

  <xsl:template match="Authentication/GetUserMenu">
    <div>
      <xsl:apply-templates select="MenuList/row"/>
    </div>
  </xsl:template>

  <xsl:template match="MenuList/row">
    <div>
      <xsl:value-of select="@MenuTitle"/>
      <div class="subMenu">
        <xsl:apply-templates select="key('k1', @MenuID)"/>
      </div>
    </div>
  </xsl:template>

  <xsl:template match="FunctionList/row">
    <div>
      <xsl:value-of select="@FunctionTitle"/>
    </div>
  </xsl:template>

</xsl:stylesheet>

使用该代码和输入发布了Saxon 6.5.5输出

<div>
   <div>menu1
      <div class="subMenu">
         <div>submenu1</div>
         <div>submenu2</div>
      </div>
   </div>
   <div>menu2
      <div class="subMenu"></div>
   </div>
   <div>menu3
      <div class="subMenu">
         <div>submenu2</div>
      </div>
   </div>
   <div>menu4
      <div class="subMenu"></div>
   </div>
</div>

这不是你发布的所期望的结果,但我不确定submenu3来自哪里,因为XML输入中没有这样的项目。

答案 1 :(得分:0)

好问题,+ 1。

这种更短更简单(不使用键)的转换

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

 <xsl:template match="/">
  <div id="menu">
   <xsl:apply-templates/>
  </div>
 </xsl:template>

 <xsl:template match="MenuList/row">
  <div>
   <xsl:value-of select="@MenuTitle"/>
   <div class="subMenu">
    <xsl:apply-templates mode="extract" select=
    "../../FunctionList
              /row[@MenuID = current()/@MenuID]
    "/>
   </div>
  </div>
 </xsl:template>

 <xsl:template match="FunctionList/row" mode="extract">
   <div><xsl:value-of select="@FunctionTitle"/></div>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<Authentication isLogged="1" uid="40">
    <GetUserMenu>
        <MenuList>
            <row MenuID="1" MenuTitle="menu1"/>
            <row MenuID="2" MenuTitle="menu2"/>
            <row MenuID="3" MenuTitle="menu3"/>
            <row MenuID="4" MenuTitle="menu4"/>
        </MenuList>
        <FunctionList>
            <row FunctionID="1" FunctionTitle="submenu1" MenuID="1"
                 WorkflowName="ImportDataWithoutFile" Order="1"/>
            <row FunctionID="2" FunctionTitle="submenu2" MenuID="1"
                 WorkflowName="ImportDataFromFile" Order="2"/>
            <row FunctionID="2" FunctionTitle="submenu3" MenuID="3"
                 WorkflowName="ImportDataFromFile" Order="2"/>
        </FunctionList>
    </GetUserMenu>
</Authentication>

生成想要的正确结果

<div id="menu">
   <div>menu1<div class="subMenu">
         <div>submenu1</div>
         <div>submenu2</div>
      </div>
   </div>
   <div>menu2<div class="subMenu"/>
   </div>
   <div>menu3<div class="subMenu">
         <div>submenu3</div>
      </div>
   </div>
   <div>menu4<div class="subMenu"/>
   </div>
</div>