【问题标题】:Need help to compare two sets of nodes in xsl需要帮助比较 xsl 中的两组节点
【发布时间】:2011-12-04 12:20:57
【问题描述】:

这是我的 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 读取 &lt;MenuList&gt;&lt;row&gt; 的 MenuId 属性值。
  2. 然后在内部循环 for-each 中,我的 xsl 将该值与 &lt;row&gt;&lt;FunctionList&gt; 的 MenuAttribute 的每个值进行比较
  3. 然后我的 xsl 读取 &lt;MenuList&gt; 的以下 &lt;row&gt; 的 MenuId 属性的值并重复第二步 通过这样做,我将能够在相应按钮下方制作 html 菜单按钮和子菜单按钮。 MenuId 属性可以识别菜单和子菜单按钮之间的连接

在普通的编程语言中,我尝试做的事情(使用 xsl)看起来像这样:

foreach (xitems as xitem)
    foreach (yitems as yitem)
       if xitem == yitem do smth

谁能提供任何建议或修改我的代码以解决我的问题?我将不胜感激

【问题讨论】:

  • 如果您需要有关将 XML 输入转换为一些 HTML 输出的 XSLT 方法的帮助,请考虑显示一个小而有代表性的 XML 输入示例以及您要创建的相应 HTML 输出。然后我们可以帮助编写正确的 XSLT 代码。将“普通”编程语言中的代码“翻译”为 XSLT 代码并不是解决 XSLT 问题的好方法。
  • 我已经发布了预期的 html 输出。如果您缺少更多详细信息,请告诉我。我会很感激一些帮助

标签: xml templates xslt foreach


【解决方案1】:

我认为您想使用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 输入中没有这样的项目。

【讨论】:

    【解决方案2】:

    好问题,+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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 2011-10-11
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      相关资源
      最近更新 更多