Синтаксический анализ XML с помощью XSLT. - PullRequest
0 голосов
/ 24 февраля 2019

Привет У меня есть следующий код XML:

<?xml version="1.0" encoding="utf-8"?>
<UserStaging>
            <NeuroRKStaging>
               <Stage Type="REM" Start="0" />
               <Stage Type="Stage3" Start="150" />
               <Stage Type="Movement" Start="3030" />
               <Stage Type="Wake" Start="3150" />
               <Stage Type="Stage2" Start="4680" />
               <Stage Type="Stage3" Start="5340" />
               <Stage Type="Movement" Start="6090" />
               <Stage Type="Wake" Start="6480" />
               <Stage Type="Stage1" Start="9330" />
               <Stage Type="Stage3" Start="10290" />
            </NeuroRKStaging>
</UserStaging>

И я должен получить его в этом формате:

<?xml version="1.0" encoding="utf-8"?>
<stages>
    <epoch><epoch_start>0</epoch_start><epoch_end>150</epoch_end><stage>REM</stage></epoch>   
    <epoch><epoch_start>150</epoch_start><epoch_end>3150</epoch_end><stage>NREM3</stage></epoch>
    <epoch><epoch_start>3150</epoch_start><epoch_end>4680</epoch_end><stage>Wake</stage></epoch>
    <epoch><epoch_start>4680</epoch_start><epoch_end>5340</epoch_end><stage>NREM2</stage></epoch>
    <epoch><epoch_start>5340</epoch_start><epoch_end>6480</epoch_end><stage>NREM3</stage></epoch>
    <epoch><epoch_start>6480</epoch_start><epoch_end>9330</epoch_end><stage>Wake</stage></epoch>
    <epoch><epoch_start>9330</epoch_start><epoch_end>10290</epoch_end><stage>NREM1</stage></epoch>
    <epoch><epoch_start>10290</epoch_start><epoch_end>99999</epoch_end><stage>NREM3</stage></epoch>
</stages>

Есть 5 типов / этапов

Stage1 transforms to NREM1
Stage2 transforms to NREM2
Stage3 transforms to NREM3
REM remains REM
Wake remains Wake

Все строки с Type = "Movement" должны быть удалены и только после этого данные должны быть преобразованы.«Начало» каждой следующей стадии будет «концом эпохи» предыдущего.Для последней эпохи epoch_end должен быть 99999

Как будет выглядеть таблица стилей xsl для этого?

1 Ответ

0 голосов
/ 24 февраля 2019

С XSLT 3 xsl:iterate вы можете передать ранее обработанный элемент и затем вывести его с правильными начальными и конечными значениями, также позаботившись о последнем элементе с xsl:on-completion:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:param name="default-end" as="xs:integer" select="99999"/>

  <xsl:param name="type-map" as="map(xs:string, xs:string)"
    select="map { 'Stage1' : 'NREM1', 'Stage2' : 'NREM2', 'Stage3' : 'NREM3' }"/>

  <xsl:output indent="yes"/>

  <xsl:template match="NeuroRKStaging">
      <stages>
          <xsl:iterate select="Stage[not(@Type = 'Movement')]">
              <xsl:param name="previous" as="element()?" select="()"/>
              <xsl:on-completion>
                  <xsl:if test="$previous">
                      <epoch>
                      <epoch_start>{$previous/@Start}</epoch_start>
                      <epoch_end>{$default-end}</epoch_end>
                      <xsl:apply-templates select="$previous/@Type"/>
                  </epoch>
                  </xsl:if>
              </xsl:on-completion>
              <xsl:if test="$previous">
                  <epoch>
                      <epoch_start>{$previous/@Start}</epoch_start>
                      <epoch_end>{@Start}</epoch_end>
                      <xsl:apply-templates select="$previous/@Type"/>
                  </epoch>
              </xsl:if>
              <xsl:next-iteration>
                  <xsl:with-param name="previous" select="."/>
              </xsl:next-iteration>
          </xsl:iterate>
      </stages>
  </xsl:template>

  <xsl:template match="Stage/@Type">
      <stage>{.}</stage>
  </xsl:template>

  <xsl:template match="Stage/@Type[map:contains($type-map, .)]">
      <stage>{$type-map(.)}</stage>
  </xsl:template>

</xsl:stylesheet>

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

...