2011-02-14 105 views
1

我在XSLT 1.0中建立无冗余依赖关系时遇到问题。我有一个节点类型a,节点类型ba依赖于b - 如果我遇到a,并且没有b已经存在,我应该插入一个。此外,我不应该改变任何其他情况。在xslt中建立依赖关系

输入:

<variables> 
    <var Value="a"/> 
</variables> 

输出:

<variables> 
    <var Value="a"/> 
    <var Value="b"/> 
</variables> 

我有困难的是,我不知道如何寻找ab相同的模板内。我可以搜索a,并用ab来代替它,但是当我们都在那里时,我发现自己有冗余。我可以搜索ab,并与一个b替换的第一个实例,但这时如果我只有b,我会包括一个没有希望。我不知道如何搜索a,然后,如果我找到它,搜索同级节点b

+0

好问题,+1。请参阅我的答案,以获得采用最基本的XSLT设计模式的完整,简短且简单的解决方案。也提供了广泛的解释。 :) – 2011-02-14 14:06:57

回答

4

这种转变

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

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

<xsl:template match= 
"var[@Value='a' and not(../var[@Value='b'])]"> 

    <xsl:call-template name="identity"/> 
    <var Value="b"/> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<variables> 
    <var Value="a"/> 
</variables> 

产生想要的,正确的结果:

<variables> 
    <var Value="a"/> 
    <var Value="b"/> 
</variables> 

说明

  1. 身份规则/模板拷贝的每一个节点 “原样”。使用和覆盖身份规则是最基本和最强大的XSLT设计模式。

  2. 只有一个多个模板 - 重写身份规则任何var元素,其Value属性为"a"不具有Value属性与价值"b"同级var元素的值。该模板复制其匹配元素,然后根据需要创建一个新的var元素。

+0

不是“not(../ var [@ Value ='v'])”选择相同的节点和属性,因此将始终为真? 认为我们应该使用`not(next-sibling :: var [@ Value ='b'])“。这应该给我们所有节点带一个A,没有后面的B. – 2011-02-14 14:06:49