我正在尝试将以下XML1转换为XML2。但无法做到,也无法找到类似的例子。罐头有人帮忙。这是我第一次尝试使用XSLT转换XML。
XML1(当前XML):
<Data>
<Set label="NY">
<value>42.000000000000000</value>
<value>339.000000000000000</value>
</Set>
<Set label="NJ">
<value>0.000000000000000</value>
<value>14.000000000000000</value>
</Set>
<Set label="TN">
<value>0.000000000000000</value>
<value>14.000000000000000</value>
</Set>
</Data>
XML 2(所需的XML):
<Data>
<Set1 label="NY">
<datapoint1>42.000000000000000</datapoint1>
</Set1>
<Set1 label="NJ">
<datapoint1>0.000000000000000</datapoint1>
</Set1>
<Set1 label="TN">
<datapoint1>0.000000000000000</datapoint1>
</Set1>
<Set2 label="NY">
<datapoint2>339.000000000000000</datapoint2>
</Set2>
<Set2 label="NJ">
<datapoint2>14.000000000000000</datapoint2>
</Set2>
<Set2 label="TN">
<datapoint2>14.000000000000000</datapoint2>
</Set2>
</Data>
答案 0 :(得分:1)
这是XSLT V1.0。请让我知道这对你有没有用。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="var1_initial" select="."/>
<Data>
<xsl:for-each select="Data/Set">
<xsl:variable name="var2_current" select="."/>
<Set1>
<xsl:attribute name="label">
<xsl:value-of select="@label"/>
</xsl:attribute>
<xsl:for-each select="value">
<xsl:variable name="var3_current" select="."/>
<datapoint1>
<xsl:value-of select="number(.)"/>
</datapoint1>
</xsl:for-each>
</Set1>
</xsl:for-each>
<xsl:for-each select="Data/Set">
<xsl:variable name="var4_current" select="."/>
<Set2>
<xsl:attribute name="label">
<xsl:value-of select="@label"/>
</xsl:attribute>
<xsl:for-each select="value">
<xsl:variable name="var5_current" select="."/>
<datapoint2>
<xsl:value-of select="number(.)"/>
</datapoint2>
</xsl:for-each>
</Set2>
</xsl:for-each>
</Data>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
这是另一个XSLT 1.0选项...
XML输入
<Data>
<Set label="NY">
<value>42.000000000000000</value>
<value>339.000000000000000</value>
</Set>
<Set label="NJ">
<value>0.000000000000000</value>
<value>14.000000000000000</value>
</Set>
<Set label="TN">
<value>0.000000000000000</value>
<value>14.000000000000000</value>
</Set>
</Data>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*|Set/value[1]"/>
<xsl:apply-templates select="Set/value[2]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="value">
<xsl:variable name="pos">
<xsl:number/>
</xsl:variable>
<xsl:element name="Set{$pos}">
<xsl:copy-of select="../@label"/>
<datapoint><xsl:value-of select="."/></datapoint>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML输出
<Data>
<Set1 label="NY">
<datapoint>42.000000000000000</datapoint>
</Set1>
<Set1 label="NJ">
<datapoint>0.000000000000000</datapoint>
</Set1>
<Set1 label="TN">
<datapoint>0.000000000000000</datapoint>
</Set1>
<Set2 label="NY">
<datapoint>339.000000000000000</datapoint>
</Set2>
<Set2 label="NJ">
<datapoint>14.000000000000000</datapoint>
</Set2>
<Set2 label="TN">
<datapoint>14.000000000000000</datapoint>
</Set2>
</Data>
如果value
元素的数量未知或可能会有所不同,那么还有一个选项......
XML输入(已修改为具有不同数量的value
元素)
<Data>
<Set label="NY">
<value>42.000000000000000</value>
<value>339.000000000000000</value>
</Set>
<Set label="NJ">
<value>0.000000000000000</value>
<value>14.000000000000000</value>
<value>77.000000000000000</value>
</Set>
<Set label="TN">
<value>0.000000000000000</value>
<value>14.000000000000000</value>
<value>77.000000000000000</value>
<value>18.000000000000000</value>
</Set>
</Data>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!--Create a key of sets based on the number of values.-->
<xsl:key name="sets" match="Set" use="count(value)"/>
<!--Determine the max number of values in a set. (Using key above.)-->
<xsl:variable name="maxValues">
<xsl:for-each select="/Data/Set[count(.|key('sets',count(value))[1])=1]">
<xsl:sort select="count(value)" order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="count(value)+1"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!--Identity transform. Copies attributes and nodes unchanged.-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Data">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:call-template name="processSets">
<xsl:with-param name="currentIteration" select="1"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="processSets">
<xsl:param name="currentIteration"/>
<xsl:apply-templates select="Set/value[position()=$currentIteration]"/>
<xsl:if test="$maxValues > $currentIteration + 1">
<xsl:call-template name="processSets">
<xsl:with-param name="currentIteration" select="$currentIteration + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="value">
<xsl:variable name="pos">
<xsl:number/>
</xsl:variable>
<xsl:element name="Set{$pos}">
<xsl:apply-templates select="../@label"/>
<datapoint><xsl:value-of select="."/></datapoint>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML输出
<Data>
<Set1 label="NY">
<datapoint>42.000000000000000</datapoint>
</Set1>
<Set1 label="NJ">
<datapoint>0.000000000000000</datapoint>
</Set1>
<Set1 label="TN">
<datapoint>0.000000000000000</datapoint>
</Set1>
<Set2 label="NY">
<datapoint>339.000000000000000</datapoint>
</Set2>
<Set2 label="NJ">
<datapoint>14.000000000000000</datapoint>
</Set2>
<Set2 label="TN">
<datapoint>14.000000000000000</datapoint>
</Set2>
<Set3 label="NJ">
<datapoint>77.000000000000000</datapoint>
</Set3>
<Set3 label="TN">
<datapoint>77.000000000000000</datapoint>
</Set3>
<Set4 label="TN">
<datapoint>18.000000000000000</datapoint>
</Set4>
</Data>