Многоуровневый список XSLT в зависимости от названия категории - PullRequest
0 голосов
/ 01 октября 2019

Я хочу создать многоуровневый вложенный список, в зависимости от названия категории. Это мой xml:

<UserDefinedTable xmlns="DotNetNuke/UserDefinedTable">
  <Data>
    <UserDefinedRowId>28</UserDefinedRowId>
    <Category>KatOne</Category>
    <Title>Level 1</Title>
  </Data>
  <Data>
    <UserDefinedRowId>29</UserDefinedRowId>
    <Category>KatOneSub</Category>
    <Title>Level 2</Title>
  </Data>
  <Data>
    <UserDefinedRowId>30</UserDefinedRowId>
    <Category>KatOneSub</Category>
    <Title>Level 2</Title>
  </Data>
  <Data>
    <UserDefinedRowId>31</UserDefinedRowId>
    <Category>KatTwo</Category>
    <Title>Level 1</Title>
  </Data>
  <Data>
    <UserDefinedRowId>32</UserDefinedRowId>
    <Category>KatTwoSub</Category>
    <Title>Level 2</Title>
  </Data>
  <Data>
    <UserDefinedRowId>33</UserDefinedRowId>
    <Category>KatTwoSub</Category>
    <Title>Level 2</Title>
  </Data>
</UserDefinedTable>

И это моя попытка шаблона XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:udt="DotNetNuke/UserDefinedTable" exclude-result-prefixes="udt">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

  <xsl:variable name="prefix_param">udt_<xsl:value-of select="//udt:Context/udt:ModuleId" />_param</xsl:variable>

  <xsl:template match="udt:Data" mode="list">

    <xsl:for-each select="udt:Data">
    <li>
        <span>KatUpper</span>

        <ul class="level-two">
            <xsl:for-each select="udt:Data">
                <li>
                    KatSub
                </li>
            </xsl:for-each>
        </ul>                   

    </li>
    </xsl:for-each>

  </xsl:template>

  <xsl:template match="/udt:UserDefinedTable">
    <xsl:variable name="currentData" select="udt:Data" />
    <xsl:if test="$currentData">
    <ul class="my-list">
      <xsl:apply-templates select="$currentData" mode="list">
      </xsl:apply-templates>
    </ul>
    </xsl:if>
  </xsl:template>

  <xsl:template name="EditLink">
    <xsl:if test="udt:EditLink">
      <a href="{udt:EditLink}">
        <img border="0" alt="edit" src="{//udt:Context/udt:ApplicationPath}/images/edit.gif" />
      </a>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Я хотел бы сделать foreach, который проверяет, соответствует ли название катехогризма тому или иномузатем он остается на верхнем уровне, и внутри каждой итерации я бы проверял, чтобы имя категории имело вложенный список внутри:

Примерно так:

<ul class="my-list">
    <li>
        <span>KatOne</span>

        <ul clasS="levelTwo">
            <li>
                KatOneSub
            </li>
            <li>
                KatOneSub
            </li>
            <li>
                KatOneSub
            </li>
        </ul>
    </li>
    <li>
        <span>KatTwo</span>

        <ul clasS="levelTwo">
            <li>
                KatTwoSub
            </li>
            <li>
                KatTwoSub
            </li>
        </ul>
    </li>
</ul>

1 Ответ

0 голосов
/ 01 октября 2019

Ваша текущая проблема заключается в том, что в шаблоне, соответствующем udt:Data, вы делаете <xsl:for-each select="udt:Data">, но он будет искать дочерние элементы текущего элемента Data, который также называется Data. Вы действительно должны искать братьев и сестер здесь.

В XSLT 1.0 вы можете использовать клавишу для поиска элементов «Уровня 2» на основе первых предыдущих элементов «Уровня 1»

<xsl:key name="level2" 
         match="udt:Data[udt:Title='Level 2']" 
         use="preceding-sibling::udt:Data[udt:Title='Level 1'][1]/udt:UserDefinedRowId" />

Затем вы начнете с выбора предметов "Уровень 1"

<xsl:variable name="currentData" select="udt:Data[udt:Title='Level 1']" />

<xsl:apply-templates select="$currentData" mode="list" />

Затем, чтобы получить предметы "Уровень 2" для текущего предмета "Уровень 1", вы можете использоватьключ

<xsl:for-each select="key('level2', udt:UserDefinedRowId)">

Попробуйте это XSLT

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:udt="DotNetNuke/UserDefinedTable" 
                exclude-result-prefixes="udt">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

  <xsl:key name="level2" 
           match="udt:Data[udt:Title='Level 2']" 
           use="preceding-sibling::udt:Data[udt:Title='Level 1'][1]/udt:UserDefinedRowId" />

  <xsl:template match="udt:Data" mode="list">
    <li>
      <span>
        <xsl:value-of select="udt:Category" />
      </span>
      <xsl:if test="key('level2', udt:UserDefinedRowId)">
        <ul class="levelTwo">
          <xsl:for-each select="key('level2', udt:UserDefinedRowId)">
            <li>
              <span>
                <xsl:value-of select="udt:Category" />
              </span>
            </li>
          </xsl:for-each>
        </ul>
      </xsl:if>
    </li>      
  </xsl:template>

  <xsl:template match="/udt:UserDefinedTable">
    <xsl:variable name="currentData" select="udt:Data[udt:Title='Level 1']" />
    <xsl:if test="$currentData">
      <ul class="my-list">
        <xsl:apply-templates select="$currentData" mode="list" />
      </ul>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Обратите внимание, что вы должны изменить выражения, такие как Title="Level 1", соответственно, если у вас есть лучший способ идентификации элементов уровня 1 и уровня 2.

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