преобразование шаблона xslt из xml из заданного xml ввода в ожидаемый xml вывод - PullRequest
0 голосов
/ 18 июня 2020

Часть входных данных xml, которая требует времени для решения требуемых выходных данных.

<contrib-group>
    <contrib contrib-type="editor">
        <name>
            <surname>John</surname>
            <given-names>Cover B.</given-names>
        </name>
        <xref ref-type="aff" rid="aff1">
            <sup>1,2</sup>
        </xref>
    </contrib>
    <contrib contrib-type="author">
        <name>
            <surname>Peter</surname>
            <given-names>Crus J.</given-names>
        </name>
        <xref ref-type="aff" rid="aff1">
            <sup>1,3</sup>
        </xref>
        <name>
            <surname>John</surname>
            <given-names>Cruz K.</given-names>
        </name>
        <xref ref-type="aff" rid="aff1">
            <sup>1</sup>
        </xref>
    </contrib>
</contrib-group>

Часть xml ожидаемых выходных данных, которые, кажется, легко зафиксировать визуально.

<contrib-group>
    <contrib contrib-type="editor">
        <name>
            <surname>John</surname>
            <given-names>Cover B.</given-names>
        </name>
        <xref ref-type="aff" rid="aff1">
            <sup>1,2</sup>
        </xref>
    </contrib>
    <contrib contrib-type="author">
        <name>
            <surname>Peter</surname>
            <given-names>Crus J.</given-names>
        </name>
        <xref ref-type="aff" rid="aff1">
            <sup>1,3</sup>
        </xref>
    </contrib>
    <contrib contrib-type="author">
        <name>
            <surname>John</surname>
            <given-names>Cruz K.</given-names>
        </name>
        <xref ref-type="aff" rid="aff1">
            <sup>1</sup>
        </xref>
    </contrib>
</contrib-group>

Часть текущего xslt, которую необходимо исправить для получения требуемого результата.

    <xsl:template match="contrib">    
<xsl:element name="{name()}">                         
    <xsl:for-each select="name">                
        <xsl:element name="{name(parent::*)}">
            <xsl:attribute name="contrib-type">
                <xsl:value-of select="../@contrib-type"/>
            </xsl:attribute>
            <xsl:element name="{name()}">
                <xsl:for-each select="@*">
                    <xsl:attribute name="{name()}">
                        <xsl:value-of select="."/>
                    </xsl:attribute>
                </xsl:for-each>            
            <xsl:apply-templates/>
            </xsl:element>
        </xsl:element>
    </xsl:for-each>
</xsl:element>    
</xsl:template>

Трудно перебирать дочерние элементы внутри элемента contrib, который должен быть воспроизведен как родительский тег.

Обновил часть xslt. Мне нужно удалить родительский тег contrib и добавить элемент xref внутри заполненного contrib.

1 Ответ

1 голос
/ 18 июня 2020

В XSLT 3 вы можете использовать for-each-group group-starting-with plus xsl:copy select="..":

<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:strip-space elements="*"/>

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

  <xsl:template match="contrib-group">
      <xsl:copy>
          <xsl:for-each-group select="contrib/*" group-starting-with="name">
              <xsl:copy select="..">
                  <xsl:apply-templates select="@*, current-group()"/>
              </xsl:copy>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6pS2B6q

Если вы действительно используете Saxon 8, тогда это не будет выполнять XSLT 3 и xsl:copy select, но for-each-group должен работать (при условии, что это выпуск Saxon 8, реализующий XSLT 2, я думаю, что большинство выпусков Saxon 8 произошло во время разработки окончательного XSLT 2 spe c, Saxon 8.9 был первым выпуском, который реализовал окончательный XSLT 2 spe c).

Для xsl:copy select=".." в XSLT 3 вы могли использовать <xsl:element name="{name(..)}"> в XSLT 2, и вам нужно было бы адаптировать <xsl:apply-templates select="@*, current-group()"/> использовать <xsl:apply-templates select="../@*, current-group()"/>.

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