2011-12-20 83 views
2

我有下面的XML:結合在XSL 2個節點集

<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> 

有兩點需要注意:

  1. 注意如何空白<elem>元素將從源結構中刪除。
  2. 這應該適用於任何數量的<row>節點集。

我覺得這應該是簡單的,但我很努力甚至不知道從哪裏開始。幫幫我?

編輯: RE:上面#2,我不想複製初始的<row> nodeset(它用於定義新的元素)。相反,該解決方案應該適用於包含數據點的任何<row>節點集(即,如果第二個節點集連續重複5次)。

+0

ABach,對不起,我不understanr你的編輯。最好給(在問題中)一個特定的XML和想要的結果的例子。你的意思是元素名稱總是隻在第一行中定義,而所有其他行都包含這些元素的數據? – 2011-12-21 03:30:08

回答

2

這種轉變相同位置的elem的價值:

<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> 

產生WA nted,正確的結果

<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> 
+0

謝謝@Dimitre。你的回答 - 特別是關於跳過甚至'nodesets'的部分 - 讓我意識到我沒有給出足夠的清晰度。如果你能閱讀我上面的修改並修改你的答案,我將不勝感激。謝謝! – ABach 2011-12-21 03:19:18

+0

@ABach:請看看我更新的答案 - 希望我這次瞭解這個問題:) – 2011-12-21 03:50:58

+0

就是這樣!非常感謝,@Dimitre - 感謝您的幫助。 – ABach 2011-12-21 05:29:10

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元素每個奇數行,我們搶在該行的下面兄弟
+0

謝謝@lwburk。你的回答 - 特別是關於跳過甚至'nodesets'的部分 - 讓我意識到我沒有給出足夠的清晰度。如果你能閱讀我上面的修改並修改你的答案,我將不勝感激。謝謝! – ABach 2011-12-21 03:16:12