2012-02-10 68 views
0

我有一個XML文檔,其中有幾個<item>元素。在每個內部,可能有一個或多個以下元素:<list>,<listAfter><listBefore>。所以,忽略了很多外來的元素,它可能是這樣的:基於條件邏輯通過XSL合併節點

<items> 
    <item> 
    <!-- ... various elements ... --> 
    <list>Enhancements</list> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <listBefore>Enhancements</listBefore> 
    <listAfter>Bugs</listAfter> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <list>Enhancements</list> 
    <listAfter>Next Release</listAfter> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <listBefore>Bugs</listBefore> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    </item> 
</items> 

我想刪除所有不必要<list*>元素組成,並且每一個<item>元素<list>。該元素的值應遵循以下邏輯:

  • 如果可用,則使用值<list>
  • 否則,如果可用,則使用值<listAfter>
  • 否則,如果可用,則使用值<listBefore>
  • 如果這些字段都不存在,請使用No List作爲值。

用我上面的XML文檔,這就是我所期望的輸出看起來像:

<items> 
    <item> 
    <!-- ... various elements ... --> 
    <list>Enhancements</list> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <list>Bugs</list> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <list>Enhancements</list> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <list>Bugs</list> 
    </item> 
    <item> 
    <!-- ... various elements ... --> 
    <list>No List</list> 
    </item> 
</items> 

除了使用恆等變換的所有其他元素,以複製,我不知道如何以一種很好的方式包含這個邏輯。一如既往,您的幫助非常感謝。

回答

1

您可以通過覆蓋標識模板並添加額外的模板來匹配各種列表元素的標準來實現。

要匹配listAfter要在輸出中要包括,你會做以下(即listAfter元素沒有列表元素作爲同級)

<xsl:template 
    match="listAfter[not(preceding-sibling::list|following-sibling::list)]"> 

對於listBefore ,只有在沒有名單而不是名單後元素作爲兄弟姐妹

<xsl:template 
    match="listBefore[not(
    preceding-sibling::list|following-sibling::list 
    |preceding-sibling::listAfter|following-sibling::listAfter)]"> 

在其他情況下,你會忽略listAfterlistBefore元素:

<xsl:template match="listAfter|listBefore" /> 

最後,你可以匹配項目元素與無各種列表中的元素像這樣的孩子:

<xsl:template match="item[not(list|listAfter|listBefore)]"> 

因此,給定以下XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="listAfter[not(preceding-sibling::list|following-sibling::list)]"> 
     <list> 
     <xsl:apply-templates select="@*|node()"/> 
     </list> 
    </xsl:template> 

    <xsl:template match="listBefore[not(preceding-sibling::list|following-sibling::list|preceding-sibling::listAfter|following-sibling::listAfter)]"> 
     <list> 
     <xsl:apply-templates select="@*|node()"/> 
     </list> 
    </xsl:template> 

    <xsl:template match="listAfter|listBefore" /> 

    <xsl:template match="item[not(list|listAfter|listBefore)]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     <list>No List</list> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

當這個被施加到源XML,下面是輸出:

<items> 
    <item> 
     <!-- ... various elements ... --> 
     <list>Enhancements</list> 
    </item> 
    <item> 
     <!-- ... various elements ... --> 
     <list>Bugs</list> 
    </item> 
    <item> 
     <!-- ... various elements ... --> 
     <list>Enhancements</list> 
    </item> 
    <item> 
     <!-- ... various elements ... --> 
     <list>Bugs</list> 
    </item> 
    <item> 
     <!-- ... various elements ... --> 
     <list>No List</list> 
    </item> 
</items> 
+0

真棒。我仍然習慣於爲XSLT思考正確的思維方式;謝謝你的幫助! – ABach 2012-02-11 21:24:09