XSl - 需要转型帮助
我是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"/>
请帮忙。提前致谢。
萝拉
这个简单的(短,只有一个模板,无模式,无轴)和强大的(参数与任何可能的组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"/>
说明:使用范围:
<xsl:variable>
AVT(属性值模板)。
XSLT处理模型和文本节点的内置模板。
在我的愚见,它不值得复杂的答案,因此,只是为了使可能重用一些文字元素。 –
请注意,这里的缩进会导致您的回答很难理解。 –
@empo:为什么你认为比你短两倍的解决方案是“复杂”的? :) –
如果您不需要参数变换,两个模板与文字结果元素(不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]">
因此,使事情变得更简单。
为什么任何人都应该使用这样的冗余代码?不仅浪费空间,而且还有问题的可维护性。 –
@Dimitre我没有在意这里关于可重用性。关于空间,它没有使用太多的空间比在你的模板。我获得可读性。 –
你必须非常困惑,@empo说你具有不同轴,3个模板和两种不同模式的复杂表达式“可读性”......,以及大量的重复/冗余和代码...... –
好问题,+1。请参阅我的答案,获取简短而简单的解决方案。 :) –