Слияние и наследование параметров - PullRequest
0 голосов
/ 19 октября 2018

Использование xslt версии 3.0 (саксонский):

У меня есть что-то вроде следующего

<root>
  <template ID='1'>
    <params>
      <a>1</a>
      <b>1</b>
    </params>
  </template>

  <document1 templateID='1'>
    <params>
      <b>4</b>
      <c>5</c>
    </params>
  </document1>

</root>

В основном мне нужно преобразовать во что-то вроде

  <root>
    <document1 templateID='1'>
      <params>
        <a>1</a>
        <b>4</b>
        <c>5</c>
      </params>
    </document1>
  </root>

Впример параметра a наследуется от шаблона, а параметр b перезаписывается самим документом, а параметр c неизвестен или не установлен в шаблоне.Это сродни наследованию или как работает CSS.Я надеюсь, вы поняли идею.Перед началом задачи я подумал, что это не должно быть слишком сложно (и все еще надеялся, что я просто что-то упустил).

Я пробовал что-то с конкатетацией двух узлов (используя nodeset1 , nodeset2 для сохранения порядка) ииспользуя «select» / «filtering» на основе имени предшествующего брата, но эта стратегия, похоже, не работает, так как кажется, что они не являются реальными братьями и сестрами.Может ли это быть сделано с умной группой?Можно ли это сделать вообще?(Я думаю, что может)

Я использую xslt версии 3.0 (саксонская)

1 Ответ

0 голосов
/ 19 октября 2018

Я думаю, что вы хотите сгруппировать или объединить, объединение в 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:output indent="yes"/>

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

  <xsl:key name="template-by-id" match="template" use="@ID"/>

  <xsl:template match="template"/>

  <xsl:template match="*[@templateID]/params">
      <xsl:copy>
          <xsl:merge>
              <xsl:merge-source name="template" select="key('template-by-id', ../@templateID)/params/*">
                  <xsl:merge-key select="string(node-name())"/>
              </xsl:merge-source>
              <xsl:merge-source name="doc" select="*">
                  <xsl:merge-key select="string(node-name())"/>
              </xsl:merge-source>
              <xsl:merge-action>
                  <xsl:copy-of select="(current-merge-group('doc'), current-merge-group('template'))[1]"/>
              </xsl:merge-action>
          </xsl:merge>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / jyH9rN8 /

группировкабыло бы

<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:output indent="yes"/>

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

  <xsl:key name="template-by-id" match="template" use="@ID"/>

  <xsl:template match="template"/>

  <xsl:template match="*[@templateID]/params">
      <xsl:copy>
          <xsl:for-each-group select="key('template-by-id', ../@templateID)/params/*, *" group-by="node-name()">
              <xsl:copy-of select="head((current-group()[2], .))"/>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / jyH9rN8 / 1

Я думаю, что xsl:merge требует, чтобы ввод был отсортирован по любому ключу слиянияили сначала отсортировать входные данные, приведенная выше группировка проще и надежнее, если только ваши дочерние элементы params действительно не названы с отсортированными буквами или словами из алфавита.

...