XSLT-1.0 | Получить первый и последний узел и вызвать конкретный шаблон - PullRequest
0 голосов
/ 04 июня 2019

Я относительно новичок в XLST, и это может быть типичной проблемой для начинающих, но я не могу понять это.Надеюсь, вы сможете помочь и понять меня.Заранее спасибо.: -)

Я пытаюсь преобразовать большой XML-файл в другой, но не могу понять, как мне получить первый и последний узел и окружить их другими узлами.

проблема в том, что все фрукты -узлы создаются итеративно.

По моему мнению, я должен добавить окружающие фрукты -узлы после всех фрукты -элементы созданы.

Я уже пробовал что-то вроде:

<xsl:template name="tplFruit" match="PARENT_FRUIT">
   <xsl:apply-template select="(//element[@name='fruit'])[1]" />
</xsl:template>

<xsl:template name="addFruits">
   <fruits>
</xsl:template>
<xsl:template name="tplFruit" match="PARENT_FRUIT">
   <xsl:apply-template select="(//element[@name='fruit'])[last()]" />
</xsl:template>

<xsl:template name="addFruits">
   </fruits>
</xsl:template>

Но это не работает, и я уверен, что произойдет другая ошибка, потому что я открываю и закрываю элементы фрукты в разных шаблонах.

Дан следующий XML (Input - XML):

<root>
... other elements ...

<PARENT_FRUIT>
   <different_node nr="1" />
   <different_node nr="2" />
   <different_node nr="3" />

   <fruit>
      <name>Apple</name>
      <calorien>999</calorien>
      <color>red</color>
   </fruit>
   <fruit>      
      <name>cherry</name>
      <calorien>999</calorien>
      <color>red</color></fruit>
   <fruit>
      <name>banana</name>
      <calorien>999</calorien>
      <color>red</color>
   </fruit>

   <different_node nr="4" />
   <different_node nr="5" />
   <different_node nr="6" />

   <fruit>
      <name>Apple2</name>
      <calorien>999</calorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>cherry2</name>
      <calorien>999</calorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>banana2</name>
      <calorien>999</calorien>
      <color>red</color>
   </fruit>

...and so on...
</PARENT_FRUIT>

...other elements ...
</root>

Мой конечный результат должен быть следующим XML:

<root>
... other elements ...

<PARENT_FRUIT>
... other elements ...

<fruits>
   <fruit>
      <name>apple</name>
      <calorien>999</carlorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>cherry</name>
      <calorien>999</carlorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>banana</name>
      <calorien>999</carlorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>apple2</name>
      <calorien>999</carlorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>cherry2</name>
      <calorien>999</carlorien>
      <color>red</color>
   </fruit>
   <fruit>
      <name>banana2</name>
      <calorien>999</carlorien>
      <color>red</color>
   </fruit>

... and so on ...
<fruits>

... other elements ...
<PARENT_FRUIT>

... other elements ...
</root>

РЕДАКТИРОВАТЬ 04.06.2019:

Я использую XLST версии 1.0

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Можно сопоставить с fruit[1] и обернуть все элементы fruit в контейнер fruits и сопоставить с другими элементами fruit, чтобы они не обрабатывались:

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

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

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

  <xsl:template match="fruit[1]">
      <fruits>
          <xsl:copy-of select="../fruit"/>
      </fruits>
  </xsl:template>

  <xsl:template match="fruit[position() > 1]"/>

</xsl:stylesheet>
0 голосов
/ 04 июня 2019

Если вы можете жить со всеми другими элементами , сгруппированными в начале, следующая простая таблица стилей XSLT-1.0 сделает эту работу.В противном случае было бы неясно, где вы хотите разместить элемент <fruits>.

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

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

    <xsl:template match="PARENT_FRUIT">
        <xsl:copy>
            <xsl:apply-templates select="*[not(self::fruit)]|@*"/>
            <fruits>
                <xsl:apply-templates select="fruit"/>
            </fruits>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Его вывод:

<?xml version="1.0"?>
<root>
    ... other elements ...

    <PARENT_FRUIT>
        <different_node nr="1"/>
        <different_node nr="2"/>
        <different_node nr="3"/>
        <different_node nr="4"/>
        <different_node nr="5"/>
        <different_node nr="6"/>
        <fruits><fruit>
                <name>Apple</name>
                <calorien>999</calorien>
                <color>red</color>
            </fruit>
            <fruit>      
                <name>cherry</name>
                <calorien>999</calorien>
                <color>red</color>
            </fruit>
            <fruit>
                <name>banana</name>
                <calorien>999</calorien>
                <color>red</color>
            </fruit>
            <fruit>
                <name>Apple2</name>
                <calorien>999</calorien>
                <color>red</color>
            </fruit>
            <fruit>
                <name>cherry2</name>
                <calorien>999</calorien>
                <color>red</color>
            </fruit>
            <fruit>
                <name>banana2</name>
                <calorien>999</calorien>
                <color>red</color>
            </fruit>
        </fruits>
    </PARENT_FRUIT>

    ...other elements ...
</root>
...