2011-08-24 136 views
2

我是XSLT新手,正在努力解決以下轉型問題。XSl - 需要轉型幫助

我有一個看起來像這樣的XML ...

<Groups> 
<Group> 
    <GroupSelector>52</GroupSelector> 
    <GroupDescription>Group 52</GroupDescription> 
    <GroupValue>ABCD</GroupValue> 
</Group> 
<Group> 
    <GroupSelector>27</GroupSelector> 
    <GroupDescription>Group 27</GroupDescription> 
    <GroupValue>PQRS</GroupValue> 
</Group> 
<Group> 
    <GroupSelector>20</GroupSelector> 
    <GroupDescription>Group 20</GroupDescription> 
    <GroupValue>XYZA</GroupValue> 
</Group> 
<Group> 
    <GroupSelector>15</GroupSelector> 
    <GroupDescription>Group 15</GroupDescription> 
    <GroupValue>MNOP</GroupValue> 
</Group> 
</Groups> 

有可能是0到n個「集團

我試圖使用XSLT找到一個‘集團’,其中'GroupSelector'的值是20並且像這樣創建輸出;

<GroupSelection ElementName="FoundGroup" Missing="false">20</GroupSelection> 
<GroupSelection ElementName="GroupDes" Missing="false">Group 20</GroupSelection> 
<GroupSelection ElementName="GroupVal" Missing="false">XYZA</GroupSelection> 

如果沒有在n「集團的具有‘GroupSelector’具有值20,輸出應該是這樣;

<GroupSelection ElementName="FoundGroup" Missing="true"/> 
<GroupSelection ElementName="GroupDes" Missing="true"/> 
<GroupSelection ElementName="GroupVal" Missing="true"/> 

請幫忙。提前致謝。

蘿拉

+0

好問題,+1。請參閱我的答案,獲取簡短而簡單的解決方案。 :) –

回答

1

這個簡單的(短,只有一個模板,無模式,無軸)和強大的(參數與任何可能的組ID工作)改造:在應用時

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

<xsl:param name="pGroupId" select="'20'"/> 

<xsl:variable name="vGroup" select= 
    "/*/Group[GroupSelector=$pGroupId]"/> 

<xsl:template match="/"> 
    <GroupSelection ElementName="FoundGroup" 
        Missing="{not($vGroup)}"> 
     <xsl:apply-templates select="$vGroup/GroupSelector"/> 
    </GroupSelection> 
    <GroupSelection ElementName="GroupDes" 
       Missing="{not($vGroup)}"> 
     <xsl:apply-templates select="$vGroup/GroupDescription"/> 
    </GroupSelection> 
    <GroupSelection ElementName="GroupVal" 
        Missing="{not($vGroup)}"> 
     <xsl:apply-templates select="$vGroup/GroupValue"/> 
    </GroupSelection> 
</xsl:template> 
</xsl:stylesheet> 

在提供的XML文檔上

<Groups> 
<Group> 
    <GroupSelector>52</GroupSelector> 
    <GroupDescription>Group 52</GroupDescription> 
    <GroupValue>ABCD</GroupValue> 
</Group> 
<Group> 
    <GroupSelector>27</GroupSelector> 
    <GroupDescription>Group 27</GroupDescription> 
    <GroupValue>PQRS</GroupValue> 
</Group> 
<Group> 
    <GroupSelector>20</GroupSelector> 
    <GroupDescription>Group 20</GroupDescription> 
    <GroupValue>XYZA</GroupValue> 
</Group> 
<Group> 
    <GroupSelector>15</GroupSelector> 
    <GroupDescription>Group 15</GroupDescription> 
    <GroupValue>MNOP</GroupValue> 
</Group> 
</Groups> 

產生想要的,正確的結果

<GroupSelection ElementName="FoundGroup" Missing="false">20</GroupSelection> 
<GroupSelection ElementName="GroupDes" Missing="false">Group 20</GroupSelection> 
<GroupSelection ElementName="GroupVal" Missing="false">XYZA</GroupSelection> 

如果上面的文件中,我們改變

<GroupSelector>20</GroupSelector> 

<GroupSelector>21</GroupSelector> 

並應用相同的變換在修改過的XML文檔上,再次想,正確的結果產生

<GroupSelection ElementName="FoundGroup" Missing="true"/> 
<GroupSelection ElementName="GroupDes" Missing="true"/> 
<GroupSelection ElementName="GroupVal" Missing="true"/> 

說明:使用範圍:

  1. <xsl:variable>

  2. AVT(屬性值模板)。

  3. XSLT處理模型和文本節點的內置模板

+0

在我的愚見,它不值得複雜的答案,因此,只是爲了使可能重用一些文字元素。 –

+0

請注意,這裏的縮進會導致您的回答很難理解。 –

+0

@empo:爲什麼你認爲比你短兩倍的解決方案是「複雜」的? :) –

3

如果您不需要參數變換,兩個模板與文字結果元素(不AVT)是不夠的:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="text()"/> 

    <xsl:template match="/*/Group[GroupSelector=20]"> 
     <GroupSelection ElementName="FoundGroup" Missing="false"> 
      <xsl:value-of select="GroupSelector"/> 
     </GroupSelection> 
     <GroupSelection ElementName="GroupDes" Missing="false"> 
      <xsl:value-of select="GroupDescription"/> 
     </GroupSelection> 
     <GroupSelection ElementName="GroupVal" Missing="false"> 
      <xsl:value-of select="GroupValue"/> 
     </GroupSelection> 
    </xsl:template> 

    <xsl:template match="/*/Group[ 
     not(following::Group) 
     and not(preceding::Group[GroupSelector=20]) 
     and not(GroupSelector=20)]"> 
     <GroupSelection ElementName="FoundGroup" Missing="true"/> 
     <GroupSelection ElementName="GroupDes" Missing="true"/> 
     <GroupSelection ElementName="GroupVal" Missing="true"/> 
    </xsl:template> 

</xsl:stylesheet> 

否則,如果該組選擇是可變的(你需要變換參數)你可以容納有用的模板模式模式將上述溶液:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:param name="selector" select="20"/> 

    <xsl:template match="/*/Group"> 
     <xsl:apply-templates select="self::*[GroupSelector=$selector]" 
      mode="selection"/> 
     <xsl:apply-templates select="self::*[ 
      not(following::Group) 
      and not(preceding::Group[GroupSelector=$selector]) 
      and not(GroupSelector=$selector)]" 
      mode="noselection"/> 
    </xsl:template> 

    <xsl:template match="Group" mode="selection"> 
     <GroupSelection ElementName="FoundGroup" Missing="false"> 
      <xsl:value-of select="GroupSelector"/> 
     </GroupSelection> 
     <GroupSelection ElementName="GroupDes" Missing="false"> 
      <xsl:value-of select="GroupDescription"/> 
     </GroupSelection> 
     <GroupSelection ElementName="GroupVal" Missing="false"> 
      <xsl:value-of select="GroupValue"/> 
     </GroupSelection> 
    </xsl:template> 

    <xsl:template match="Group" mode="noselection"> 
     <GroupSelection ElementName="FoundGroup" Missing="true"/> 
     <GroupSelection ElementName="GroupDes" Missing="true"/> 
     <GroupSelection ElementName="GroupVal" Missing="true"/> 
    </xsl:template> 

</xsl:stylesheet> 

顯然,在XSLT 2.0你可以用變量直接工作,寫類似:

<xsl:template match="/*/Group[GroupSelector=$selector]"> 

因此,使事情變得更簡單。

+0

爲什麼任何人都應該使用這樣的冗餘代碼?不僅浪費空間,而且還有問題的可維護性。 –

+0

@Dimitre我沒有在意這裏關於可重用性。關於空間,它沒有使用太多的空間比在你的模板。我獲得可讀性。 –

+0

你必須非常困惑,@empo說你具有不同軸,3個模板和兩種不同模式的複雜表達式「可讀性」......,以及大量的重複/冗餘和代碼...... –