2011-08-24 244 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个模板和两种不同模式的复杂表达式“可读性”......,以及大量的重复/冗余和代码...... –