嗨,我有以下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”。对于最后一个纪元,epoch_end应该为99999
xsl样式表如何做到这一点?
答案 0 :(得分:1)
使用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>