Плоский XML для каждой группы XSLT 1.0 - PullRequest
0 голосов
/ 16 мая 2019

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

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

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

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

У меня есть этот 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?

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

1 Ответ

1 голос
/ 16 мая 2019

Предполагая, что вы хотите сгруппировать элементы, начиная с элементов <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>
...