Проблема с подстрокой и группировкой в ​​XSLT 2.0 - PullRequest
0 голосов
/ 24 мая 2011

У меня есть следующий XML:

<InterSection criteria="Microsoft-ASP">value</Intersection>
<InterSection criteria="Microsoft-MVC">value</Intersection>
<InterSection criteria="HP-MVC">value</Intersection>

Мне нужно создать оглавление в верхней части моей HTML-страницы, поэтому мне нужно сгруппировать по критериям (первая часть перед '-').

Мне нужны разные значения, такие как

  1. Microsoft
  2. HP

Мой XSLT имеет следующий код

<a>
    <xsl:attribute name="href">
      <xsl:text>#trigger</xsl:text>
      <xsl:value-of select="position()"/>
    </xsl:attribute>
                <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">
                      <xsl:value-of select="substring-before(@Criteria, ' - ')"/> 
                      <xsl:text>
                      </xsl:text>
                    </xsl:for-each-group>        

  </a>

Но почему-то я получаю

  1. Microsoft
  2. Microsoft
  3. HP

вместо 1. Microsoft 2. HP

У меня в XSLT написано следующее

  <xsl:template match="InterSection" mode="TOC">

<li>
  <a>
    <xsl:attribute name="href">
      <xsl:text>#trigger</xsl:text>
      <xsl:value-of select="position()"/>
    </xsl:attribute>

    <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">
        <xsl:value-of select="current-grouping-key()"/>
        <xsl:for-each select="current-group()"/>
     </xsl:for-each-group>
  </a>
</li>

Ответы [ 2 ]

1 голос
/ 25 мая 2011
           <xsl:for-each-group select="." group-by="substring-before(@Criteria, ' - ')">

Это бессмысленно. Выражение в атрибуте select выбирает отдельный элемент . Группировка имеет смысл, когда выбрано более одного элемента, и мы хотим сгруппировать их по определенным критериям.

Когда один элемент «сгруппирован», «результатом» всегда является тот же элемент - это именно то, что вы получаете.

Решение : правильно выберите группу элементов, которые нужно сгруппировать. Или используйте это альтернативное решение:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vallKeys" select=
  "distinct-values
      (/*/*/@criteria
            /substring-before(.,'-')
      )
  "/>
 <xsl:template match="/">
  <xsl:for-each select="$vallKeys">
   <xsl:value-of select=
     "concat(position(),'.',.,'&#xA;')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к следующему XML-документу (получено из предоставленного фрагмента путем исправления его серьезного искажения):

<someParent>
    <InterSection criteria="Microsoft-ASP">value</InterSection>
    <InterSection criteria="Microsoft-MVC">value</InterSection>
    <InterSection criteria="HP-MVC">value</InterSection>
</someParent>

желаемый, правильный результат получается :

1.Microsoft
2.HP
1 голос
/ 25 мая 2011

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

  • Ваши входные xml-элементы не в правильном регистре
  • в своем преобразовании вы ссылаетесь на атрибут criteria, используя неправильный регистр
  • ваше substring выражение содержит слишком много пробелов вокруг второго аргумента -
  • Вы должны использовать current-grouping-key(), чтобы получить значение текущей совпадающей группы
  • шаблон должен соответствовать родительскому элементу InterSection (Root), а затем вы должны выполнить итерацию на InterSection, как если бы вы сделали xsl:for-each
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...