Преобразование XML - переместить childNode в другой parentNode, если достигнуто максимальное вхождение - PullRequest
0 голосов
/ 22 мая 2019

Я делаю преобразование XML-XML с использованием Java (через .xsl). В настоящее время мне сложно ограничить максимальное вхождение узла и переместить остальное в другой parentNode.

Например: У меня есть XML, как показано ниже

<room>
    <box>
        <ball>1</ball>
        <ball>2</ball>
        <ball>3</ball>
        <ball>4</ball>
        <ball>5</ball>
        <ball>6</ball>
        <ball>7</ball>
    </box>
</room>

Затем мне нужно преобразовать в XML, который допускает не более 3 вхождений на элемент "box". Если оно превышает 3, будет создан новый parentNode для "box", затем поместите в него следующие 3 элемента "ball".

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

<room>
    <box>
        <ball>1</ball>
        <ball>2</ball>
        <ball>3</ball>
    </box>
    <box>
        <ball>4</ball>
        <ball>5</ball>
        <ball>6</ball>
    </box>
    <box>
        <ball>7</ball>
    </box>
</room>

Буду признателен, если кто-нибудь подскажет, как мне создать таблицу стилей XSL для этого правила.

Ответы [ 2 ]

2 голосов
/ 22 мая 2019

Простое решение XSLT-1.0 использует следующие шаблоны:

<xsl:template match="/room">
    <xsl:copy>
        <xsl:apply-templates select="box/ball[position() mod 3 = 1]" />
    </xsl:copy>
</xsl:template>

<xsl:template match="ball">
    <box>
        <xsl:copy-of select="." />
        <xsl:copy-of select="following-sibling::ball[1]" />
        <xsl:copy-of select="following-sibling::ball[2]" />
    </box>
</xsl:template>
1 голос
/ 23 мая 2019

В XSLT 2/3 это можно решить с помощью позиционной группировки <xsl:for-each-group select="ball" group-adjacent="(position() - 1) idiv $size">, например. с XSLT 3:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="size" as="xs:integer" select="3"/>

  <xsl:mode on-no-match="shallow-copy"/>

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

  <xsl:template match="box">
      <xsl:for-each-group select="ball" group-adjacent="(position() - 1) idiv $size">
          <xsl:copy select="..">
              <xsl:apply-templates select="current-group()"/>
          </xsl:copy>
      </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / 3NJ38ZA

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