我有以下XML:
<root>
<row>
<elem>Timestamp</elem>
<elem>ERB.CHW.BTU_CV</elem>
<elem>ERB.CHW.BTU1_CV</elem>
<elem>ERB.HW.BTU_CV</elem>
<elem>ERB.HW.BTU1_CV</elem>
<elem>ERB.KW.DEMAND_CV</elem>
<elem>ERB.KWH.MT_CV</elem>
<elem></elem>
</row>
<row>
<elem>2011/09/30 11:21:13.9062</elem>
<elem>2.307609E+09</elem>
<elem>1880067</elem>
<elem>1.068635E+08</elem>
<elem>1340.386</elem>
<elem>448.8</elem>
<elem>1427723</elem>
<elem></elem>
</row>
</root>
我想改变它,以便第一个<row>
定义新元素(通过<elem>
),后面的每个非空<elem>
提供值 - 例如:
<root>
<row>
<Timestamp>2011/09/30 11:21:13.9062</Timestamp>
<ERB.CHW.BTU_CV>2.307609E+09</ERB.CHW.BTU_CV>
<ERB.CHW.BTU1_CV>1880067</ERB.CHW.BTU1_CV>
<ERB.HW.BTU_CV>1.068635E+08</ERB.HW.BTU_CV>
<ERB.HW.BTU1_CV>1340.386</ERB.HW.BTU1_CV>
<ERB.KW.DEMAND_CV>448.8</ERB.KW.DEMAND_CV>
<ERB.KWH.MT_CV>1427723</ERB.KWH.MT_CV>
</row>
</root>
有两点需要注意:
<elem>
元素。<row>
节点集。我觉得这应该很简单,但我甚至都在努力想知道从哪里开始。帮助
编辑: RE:上面的#2,我不打算复制初始<row>
节点集(用于定义新元素)。相反,该解决方案应适用于包含数据点的任何<row>
节点集(即,如果第二个<row>
节点集连续重复5次)。
答案 0 :(得分:2)
以下样式表生成请求的结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- ignore even-numbered rows -->
<xsl:template match="row[position() mod 2 = 0]"/>
<!-- non-empty elem nodes of odd-numbered rows -->
<xsl:template match="elem[normalize-space()]">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{text()}">
<xsl:value-of select="../following-sibling::row[1]/elem[$pos]"/>
</xsl:element>
</xsl:template>
<xsl:template match="elem"/>
</xsl:stylesheet>
<强>解释强>:
elem
元素时,我们在该行的后续兄弟中的同一位置抓取elem
的值答案 1 :(得分:2)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vElems" select=
"/*/row[1]/elem[normalize-space()]"/>
<xsl:template match="/*">
<root>
<xsl:apply-templates select="row[position() >1]"/>
</root>
</xsl:template>
<xsl:template match="row">
<row>
<xsl:apply-templates select="$vElems">
<xsl:with-param name="pValues"
select="elem"/>
</xsl:apply-templates>
</row>
</xsl:template>
<xsl:template match="elem">
<xsl:param name="pValues"/>
<xsl:variable name="vPos" select="position()"/>
<xsl:element name="{.}">
<xsl:value-of select="$pValues[$vPos]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档(提供的另外一个数据行):
<root>
<row>
<elem>Timestamp</elem>
<elem>ERB.CHW.BTU_CV</elem>
<elem>ERB.CHW.BTU1_CV</elem>
<elem>ERB.HW.BTU_CV</elem>
<elem>ERB.HW.BTU1_CV</elem>
<elem>ERB.KW.DEMAND_CV</elem>
<elem>ERB.KWH.MT_CV</elem>
<elem></elem>
</row>
<row>
<elem>2011/09/30 11:21:13.9062</elem>
<elem>2.307609E+09</elem>
<elem>1880067</elem>
<elem>1.068635E+08</elem>
<elem>1340.386</elem>
<elem>448.8</elem>
<elem>1427723</elem>
<elem></elem>
</row>
<row>
<elem>2011/09/31 11:22:33.9063</elem>
<elem>3.418609E+10</elem>
<elem>1991073</elem>
<elem>1.068635E+08</elem>
<elem>1340.386</elem>
<elem>452.5</elem>
<elem>169578</elem>
<elem></elem>
</row>
</root>
生成想要的正确结果:
<root>
<row>
<Timestamp>2011/09/30 11:21:13.9062</Timestamp>
<ERB.CHW.BTU_CV>2.307609E+09</ERB.CHW.BTU_CV>
<ERB.CHW.BTU1_CV>1880067</ERB.CHW.BTU1_CV>
<ERB.HW.BTU_CV>1.068635E+08</ERB.HW.BTU_CV>
<ERB.HW.BTU1_CV>1340.386</ERB.HW.BTU1_CV>
<ERB.KW.DEMAND_CV>448.8</ERB.KW.DEMAND_CV>
<ERB.KWH.MT_CV>1427723</ERB.KWH.MT_CV>
</row>
<row>
<Timestamp>2011/09/31 11:22:33.9063</Timestamp>
<ERB.CHW.BTU_CV>3.418609E+10</ERB.CHW.BTU_CV>
<ERB.CHW.BTU1_CV>1991073</ERB.CHW.BTU1_CV>
<ERB.HW.BTU_CV>1.068635E+08</ERB.HW.BTU_CV>
<ERB.HW.BTU1_CV>1340.386</ERB.HW.BTU1_CV>
<ERB.KW.DEMAND_CV>452.5</ERB.KW.DEMAND_CV>
<ERB.KWH.MT_CV>169578</ERB.KWH.MT_CV>
</row>
</root>