2012-04-05 94 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文檔被改變,則無需修改。