XSL 变量分组
XSL grouping with variables
我在 XML 元素中有以下字符串:
<foodAndBeverageNutrient__>ENER-|APPROXIMATELY||120|E14++ENER-|APPROXIMATELY||501|KJO++PRO-|APPROXIMATELY||6.6|GRM++CHOAVL|APPROXIMATELY||6.9|GRM++SUGAR-|APPROXIMATELY||1.2|GRM++FAT|APPROXIMATELY||7.1|GRM++FASAT|APPROXIMATELY||1.3|GRM++FAMSCIS|APPROXIMATELY||3.8|GRM++FAPUCIS|APPROXIMATELY||2.0|GRM++FIBTG|APPROXIMATELY||1.2|GRM++SALTEQ|APPROXIMATELY||0.5|GRM</foodAndBeverageNutrient__>
使用以下带有标记化的 xsl 我可以拆分
<xsl:template name="foodAndBeverageNutrient_detail">
<xsl:for-each select="tokenize(., '\+\+')">
<xsl:variable name="foodAndBeverageNutrient" select="tokenize(., '\|')"/>
<nutrientDetail>
<nutrientTypeCode>
<xsl:value-of select="$foodAndBeverageNutrient[1]"/>
</nutrientTypeCode>
<xsl:if test="$foodAndBeverageNutrient[3] !=''">
<dailyValueIntakePercent>
<xsl:value-of select="$foodAndBeverageNutrient[3]"/>
</dailyValueIntakePercent>
</xsl:if>
<measurementPrecisionCode>
<xsl:value-of select="$foodAndBeverageNutrient[2]"/>
</measurementPrecisionCode>
<quantityContained measurementUnitCode="{$foodAndBeverageNutrient[5]}">
<xsl:value-of select="$foodAndBeverageNutrient[4]"/>
</quantityContained>
</nutrientDetail>
</xsl:for-each>
</xsl:template>
给我以下结果:
<foodAndBeverageNutrientInformation>
<preparationState>UNPREPARED</preparationState>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="ENER-"/>
<quantityContained>
<measurementValue unitOfMeasure="E14">
<value>29</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="ENER-"/>
<quantityContained>
<measurementValue unitOfMeasure="KJO">
<value>69</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="PRO-"/>
<quantityContained>
<measurementValue unitOfMeasure="GR">
<value>1.4</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="CHOAVL"/>
<quantityContained>
<measurementValue unitOfMeasure="GR">
<value>3.8</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="SUGAR-"/>
<quantityContained>
<measurementValue unitOfMeasure="GR">
<value>3.4</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
但是我需要按 nutrientType 代码分组,所以结果是像这样为每个 nutrientType 代码重复 quantityContained;
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="ENER-"/>
<quantityContained>
<measurementValue unitOfMeasure="E14">
<value>29</value>
</measurementValue>
</quantityContained>
<quantityContained>
<measurementValue unitOfMeasure="KJO">
<value>122</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
我尝试过对
将数据分组为数组序列的 XSLT 3 示例是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:template match="foodAndBeverageNutrient__">
<xsl:for-each-group select="tokenize(., '\+\+') ! array { tokenize(., '\|') }" group-by="?1">
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="{current-grouping-key()}"/>
<xsl:apply-templates select="current-group()"/>
</foodAndBeverageNutrient>
</xsl:for-each-group>
</xsl:template>
<xsl:template match=".[. instance of array(*)]">
<quantityContained measurementUnitCode="{?5}">
<value>{?4}</value>
</quantityContained>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes" method="xml"/>
</xsl:stylesheet>
我不太确定我选择了正确的数据,但你最好知道你有哪个索引,例如value
.
我在 XML 元素中有以下字符串:
<foodAndBeverageNutrient__>ENER-|APPROXIMATELY||120|E14++ENER-|APPROXIMATELY||501|KJO++PRO-|APPROXIMATELY||6.6|GRM++CHOAVL|APPROXIMATELY||6.9|GRM++SUGAR-|APPROXIMATELY||1.2|GRM++FAT|APPROXIMATELY||7.1|GRM++FASAT|APPROXIMATELY||1.3|GRM++FAMSCIS|APPROXIMATELY||3.8|GRM++FAPUCIS|APPROXIMATELY||2.0|GRM++FIBTG|APPROXIMATELY||1.2|GRM++SALTEQ|APPROXIMATELY||0.5|GRM</foodAndBeverageNutrient__>
使用以下带有标记化的 xsl 我可以拆分
<xsl:template name="foodAndBeverageNutrient_detail">
<xsl:for-each select="tokenize(., '\+\+')">
<xsl:variable name="foodAndBeverageNutrient" select="tokenize(., '\|')"/>
<nutrientDetail>
<nutrientTypeCode>
<xsl:value-of select="$foodAndBeverageNutrient[1]"/>
</nutrientTypeCode>
<xsl:if test="$foodAndBeverageNutrient[3] !=''">
<dailyValueIntakePercent>
<xsl:value-of select="$foodAndBeverageNutrient[3]"/>
</dailyValueIntakePercent>
</xsl:if>
<measurementPrecisionCode>
<xsl:value-of select="$foodAndBeverageNutrient[2]"/>
</measurementPrecisionCode>
<quantityContained measurementUnitCode="{$foodAndBeverageNutrient[5]}">
<xsl:value-of select="$foodAndBeverageNutrient[4]"/>
</quantityContained>
</nutrientDetail>
</xsl:for-each>
</xsl:template>
给我以下结果:
<foodAndBeverageNutrientInformation>
<preparationState>UNPREPARED</preparationState>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="ENER-"/>
<quantityContained>
<measurementValue unitOfMeasure="E14">
<value>29</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="ENER-"/>
<quantityContained>
<measurementValue unitOfMeasure="KJO">
<value>69</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="PRO-"/>
<quantityContained>
<measurementValue unitOfMeasure="GR">
<value>1.4</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="CHOAVL"/>
<quantityContained>
<measurementValue unitOfMeasure="GR">
<value>3.8</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="SUGAR-"/>
<quantityContained>
<measurementValue unitOfMeasure="GR">
<value>3.4</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
但是我需要按 nutrientType 代码分组,所以结果是像这样为每个 nutrientType 代码重复 quantityContained;
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="ENER-"/>
<quantityContained>
<measurementValue unitOfMeasure="E14">
<value>29</value>
</measurementValue>
</quantityContained>
<quantityContained>
<measurementValue unitOfMeasure="KJO">
<value>122</value>
</measurementValue>
</quantityContained>
</foodAndBeverageNutrient>
我尝试过对
将数据分组为数组序列的 XSLT 3 示例是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:template match="foodAndBeverageNutrient__">
<xsl:for-each-group select="tokenize(., '\+\+') ! array { tokenize(., '\|') }" group-by="?1">
<foodAndBeverageNutrient>
<measurementPrecision>APPROXIMATELY</measurementPrecision>
<nutrientTypeCode iNFOODSCodeValue="{current-grouping-key()}"/>
<xsl:apply-templates select="current-group()"/>
</foodAndBeverageNutrient>
</xsl:for-each-group>
</xsl:template>
<xsl:template match=".[. instance of array(*)]">
<quantityContained measurementUnitCode="{?5}">
<value>{?4}</value>
</quantityContained>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes" method="xml"/>
</xsl:stylesheet>
我不太确定我选择了正确的数据,但你最好知道你有哪个索引,例如value
.