2012-04-05 86 views
1

添加节点,我有以下XML结构:XSLT在正确的位置

<Main> 
    <Node1>Definite</Node1> 
    <Node2>Definite</Node2> 
    <Node3>Definite</Node3> 
    <Node4>Definite</Node4> 
    <Node5>Definite</Node5> 
    <Node6>Definite</Node6> 
    <A>Possible</A> 
    <B>Possible</B> 
    <C>Possible</C> 
    <D>Possible</D>  
    <E>Possible</E> 
    <F>Possible</F> 
    <G>Possible</G> 
    <H>Possible</H> 
    <I>Possible</I> 
</Main> 

命名为单个字母如节点。 <A>是XML结构中可能不存在的节点,而所有其他节点都是明确的。

我需要插入节点<ZZZ>结构内,使得它总是在如下所示的位置坐。

<Main> 
    <Node1>Value</Node1> 
    <Node2>Value</Node2> 
    <Node3>Value</Node3> 
    <Node4>Value</Node4> 
    <Node5>Value</Node5> 
    <Node6>Value</Node6> 
    <A>Value</A> 
    <B>Value</B> 
    <C>Value</C> 
    <D>Value</D>  
    <E>Value</E> 
    <ZZZ>Value</ZZZ> 
    <F>Value</F> 
    <G>Value</G> 
    <H>Value</H> 
    <I>Value</I> 
</Main> 

所以说,节点<E><C><H> didnt存在这将是:

<Main> 
    <Node1>Value</Node1> 
    <Node2>Value</Node2> 
    <Node3>Value</Node3> 
    <Node4>Value</Node4> 
    <Node5>Value</Node5> 
    <Node6>Value</Node6> 
    <A>Value</A> 
    <B>Value</B> 
    <D>Value</D>  
    <ZZZ>Value</ZZZ> 
    <F>Value</F> 
    <G>Value</G> 
    <I>Value</I> 
</Main> 

希望是这样解释不够清楚:)

+0

你可能有兴趣看到一个通用的解决方案,其中可能的和明确的名称是不固定的。 :) – 2012-04-05 13:01:27

回答

2

它取决于以及对哪些元素和需要选用这是可选的!例如。如果你能说<˚F>是requierd您可以将F-元素之前插入ZZZ-元素:

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

<xsl:template match="F"> 
    <ZZZ>Value</ZZZ> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
</xsl:template> 

如果你不能说,有该电源线元素,你需要在模板中插入主元素:

<xsl:template match="Main"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="Node1|Node2|Node3|Node4|Node5|Node6|A|B|C|D|E"/> 
     <ZZZ>Value</ZZZ> 
     <xsl:apply-templates select="F|G|H|I"/> 
    </xsl:copy> 
</xsl:template> 
+0

固定的,我遇到的问题:)忘了命名空间中的:)正常使用TY补充。 – Mike 2012-04-05 10:59:26

0

更一般的解决方案,可适于与任何动态specidfied名称和任何数量的明确的或可能的名字工作:

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

<my:occurences> 
    <definites> 
     <definite>Node1</definite> 
     <definite>Node2</definite> 
     <definite>Node3</definite> 
     <definite>Node4</definite> 
     <definite>Node5</definite> 
     <definite>Node6</definite> 
    </definites> 
    <possibles> 
     <possible>A</possible> 
     <possible>B</possible> 
     <possible>C</possible> 
     <possible>D</possible> 
     <possible>E</possible> 
     <possible>F</possible> 
     <possible>G</possible> 
     <possible>H</possible> 
     <possible>I</possible> 
    </possibles> 
</my:occurences> 

<xsl:variable name="vOccurencies" select= 
    "document('')/*/my:occurences"/> 

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

<xsl:template match="/*"> 
    <xsl:copy> 
    <xsl:apply-templates select= 
    "*[name() = 
     ($vOccurencies/definites/definite 
     | 
     $vOccurencies/possibles/possible 
        [not(position() 
        > 
        string-length(substring-before($vOccurencies/possibles, 'F'))) 
        ] 
     ) 
     ]"/> 
    <ZZZ>Value</ZZZ> 
    <xsl:apply-templates select= 
    "*[name() 
    = 
     $vOccurencies/possibles/possible 
        [position() 
        > 
        string-length(
         substring-before($vOccurencies/possibles, 'F') 
           ) 
        ] 
    ]"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

当这种转化应用所提供的XML文档

<Main> 
    <Node1>Value</Node1> 
    <Node2>Value</Node2> 
    <Node3>Value</Node3> 
    <Node4>Value</Node4> 
    <Node5>Value</Node5> 
    <Node6>Value</Node6> 
    <A>Value</A> 
    <B>Value</B> 
    <C>Value</C> 
    <D>Value</D> 
    <E>Value</E> 
    <ZZZ>Value</ZZZ> 
    <F>Value</F> 
    <G>Value</G> 
    <H>Value</H> 
    <I>Value</I> 
</Main> 

想要的,正确的结果产生

<Main> 
    <Node1>Value</Node1> 
    <Node2>Value</Node2> 
    <Node3>Value</Node3> 
    <Node4>Value</Node4> 
    <Node5>Value</Node5> 
    <Node6>Value</Node6> 
    <A>Value</A> 
    <B>Value</B> 
    <C>Value</C> 
    <D>Value</D> 
    <E>Value</E> 
    <ZZZ>Value</ZZZ> 
    <F>Value</F> 
    <G>Value</G> 
    <H>Value</H> 
    <I>Value</I> 
</Main> 

请注意

在一个真实世界的情况下my:occurances埃尔EMENT将其单独的XML文档中 - 因此XSLT代码有没有硬编码元素的名称和当occurencies XML文档被改变,则无需修改。