XSLT 1.0 Плоский XML для каждой группы

Мне нужно немного помощи здесь. Я новичок в XSLT.

Я знаю, что в 2.0 вы можете использовать For-Each-Group, что решит мою проблему, но я ограничен 1.0.

Что мне нужно, чтобы сгруппировать плоский XML, используя что-то вроде функции «группа, начинающаяся с».

Это только пример, но моя реальная проблема очень похожа.

У меня есть этот XML:

<?xml version="1.0" encoding="UTF-8"?>
    <catalog>

        <xpto name="1">ABC</xpto>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
        <xpto name="2">ABC</xpto>

        <xpto name="1">ABC</xpto>
        <title>Hide your heart</title>
        <artist>Bob Dylan</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
        <xpto name="2">ABC</xpto>

    </catalog>

И я хочу, чтобы это было:

<?xml version="1.0" encoding="UTF-8"?>
    <catalog>

        <group>
            <xpto name="1">ABC</xpto>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
            <xpto name="2">ABC</xpto>
        </group>

        <group>
            <xpto name="1">ABC</xpto>
            <title>Hide your heart</title>
            <artist>Bob Dylan</artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
            <xpto name="2">ABC</xpto>
        </group>

    </catalog>

Поэтому я хочу группировать элементы каждый раз, когда появляется следующее:

    <xpto name="1">ABC</xpto>

Есть ли способ сделать это с помощью XSLT 1.0?

Большое спасибо!


person Kaisers    schedule 16.05.2019    source источник
comment
Привет, добро пожаловать в StackOverflow! не могли бы вы предоставить то, что вы пробовали до сих пор?   -  person Hasta Dhana    schedule 16.05.2019


Ответы (1)


Предполагая, что вы хотите сгруппировать элементы, начинающиеся с элементов <xpto name="1">, вы можете определить ключ для группировки других дочерних элементов по первому такому элементу, который им предшествует:

 <xsl:key name="start" match="*[not(self::xpto[@name='1'])]" use="generate-id(preceding-sibling::xpto[@name='1'][1])" />

Затем вы можете выбрать все свои начальные элементы и получить другие элементы группы следующим образом:

<xsl:apply-templates select=".|key('start', generate-id())" /> 

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

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

  <xsl:key name="start" match="*[not(self::xpto[@name='1'])]" use="generate-id(preceding-sibling::xpto[@name='1'][1])" />

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

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="catalog">
    <xsl:copy>
      <xsl:for-each select="xpto[@name='1']">
        <group>
          <xsl:apply-templates select=".|key('start', generate-id())" /> 
        </group>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
person Tim C    schedule 16.05.2019
comment
Уважаемый Тим С, большое спасибо. Это решило мою проблему!! Я не могу голосовать, потому что мой профиль новый, а stackoverflow не позволяет :( - person Kaisers; 16.05.2019
comment
@Kaisers: вы можете закрыть вопрос, приняв ответ - person Vebbie; 16.05.2019
comment
Немного поиграв с ним, мне снова нужна ваша помощь. После добавления тега группы мне нужно зациклить каждую группу и получить значение исполнителя. Как я могу это сделать? Я борюсь с логикой шаблона... - person Kaisers; 16.05.2019
comment
@Kaisers, задайте новый вопрос с необходимыми подробностями. В своем первоначальном вопросе вы хотели вывести все элементы группы, и Тим показал вам, как это сделать (и как выбрать все элементы в группе с помощью .|key('start', generate-id()). Непонятно, почему вы думаете, что вам нужно зацикливаться или где/как вам нужно именно это значение. Задайте новый вопрос, объясняющий это. - person Martin Honnen; 16.05.2019