Нужна помощь для сравнения двух наборов узлов в xsl - PullRequest
0 голосов
/ 04 декабря 2011

Вот кусок моего 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>

Iхотел бы, чтобы мой xsl сделал это:

  1. Во внешнем цикле for-каждый xsl читает значение атрибута MenuId <row> из <MenuList>.
  2. , затем во внутреннем цикле для- каждый мой xsl сравнивает это значение с каждым значением MenuAttribute <row> из <FunctionList>
  3. , затем мой xsl считывает значение атрибута MenuId следующего <row> из <MenuList> и повторяет второй шагДелая это, я буду в состоянии сделать кнопки меню HTML и кнопки подменю ниже соответствующей кнопки.соединение между кнопками меню и подменю распознается атрибутом MenuId

На обычном языке программирования то, что я пытаюсь сделать (с xsl), будет выглядеть так:

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

Может кто-нибудьдать какой-либо совет или изменить мой код, чтобы решить мою проблему?Буду благодарен

Ответы [ 2 ]

0 голосов
/ 05 декабря 2011

Хороший вопрос, + 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>
0 голосов
/ 04 декабря 2011

Я думаю, что вы хотите использовать функции xsl:key и key следующим образом:

<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-входе такого элемента нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...