XSl - 需要转型帮助

时间:2011-08-24 03:21:20

标签: xslt select tags repeat

我是XSLT的新手,正在尝试解决以下转换问题。

我有一个看起来像这样的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来查找'Group',其中'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'组中没有一个具有值为20的'GroupSelector',则输出应该是这样的;

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

请帮忙。提前谢谢。

洛拉

2 个答案:

答案 0 :(得分: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]">

从而使事情变得更简单。

答案 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处理模型和文本节点的内置模板